React learning 23 (basic use of redux)

understand

1) Learning documents

        English documentation: https://redux.js.org/

        Chinese documentation: https://www.redux.org.cn/

        github:https://github.com/react.js/redux

2) What is redux

        redux is a JS library dedicated to state management (not a react plugin library)

        It can be used in react, angular, vue and other projects, but it basically works with react

        Role: Centralized management of the state shared by multiple components in the react application

3) When to use redux

        The state of a certain component needs to be obtained (shared) by other components at any time

         One component needs to change the state of another component (communication)

        General principle: if you can use it, you can’t use it. If you don’t need to work hard, you can consider using it

4) redux principle diagram

 Three core concepts of redux

1)action

        A. Action object

        B. Contains two attributes

                type: identification attribute, the value is a string, unique, required attribute

                data: data attribute, the value is any type, optional attribute

                例如:{type: 'ADD_STUDENT ', data:{name:'tom', age:18}}

2)reducer

        A. Used for initialization state and processing state

        B. A pure function that generates a new state based on the old state and action during processing

3)store

        A. The object that links state, action, and reducer together

        B. How to get this object

import {createStore} from 'redux'
import reducer from './reducers'
const store = createStore(reducer)

        C. The function of this object

                getState( ): get state

                dispatch(action): Distribute action, trigger reducer, generate new state

                subscribe(listenr): register listener, when a new state is generated, it will be called automatically

Note: Before using redux, you must first install redux: npm i redux

Summation case—redux classic version

1) Remove the state of the Count component itself

2) Create under .src

        -src -rudex folder

                -store.js

                 -count_reducer.js

3)store.js

        A. Introduce the createStore function in redux to create a store

        B. When createStore is called, a reducer that serves it must be passed in

        C. Remember to expose the store object

/*
 该文件专门用于暴露一个store对象,整个应用只有一个store对象
*/
//引入createStore,专门用于创建redux中最为核心的store对象
import {createStore} from 'redux'

//引入为Count组件服务的reducer
import countReducer from './count_reducer'

export default createStore(countReducer)

4)count_reducer.js

A. The essence of the reducer is a function that receives: PreState, action, and returns the processed function

B. The reducer has two functions: initialization state and processing state

C. When the reducer is called for the first time, it is automatically triggered by the store, and the passed preState is undefined

/*
 1.该文件用于创建一个为count组件服务的reducer,reducer的本质就是一个函数
 2.reducer函数会接到两个参数,分别是之前的state(状态)和action(动作对象)
*/

const initState = 0
export default function countReducer(preState=initState, action) {
  console.log(preState, action);
  //从action对象中获取type, data
  const {type, data} = action
  //根据type类型决定如何加工
  switch (type) {
    case 'increment':// 如果是加
     return preState + data
    case 'decrement':// 如果是减
      return preState - data
    default:
      return preState

 }
}

5) Detect the state change in the store in index.js, and re-render once the sound changes

Remarks: redux is only responsible for state management. As for the display of state-driven pages, it is up to us

import React from 'react'
import ReactDOM from 'react-dom'
import App from './App.jsx'
import store from './redux/store'

ReactDOM.render(<App/>,document.getElementById('root'))

store.subscribe(() => {
  ReactDOM.render(<App/>,document.getElementById('root'))
})

Summation case—full version of redux

new file

1.count_actions, js, is specially used to create action objects, which is essentially an object

2.constants.js, place the type in the wrong action due to coding negligence

count_action.js

/*
 该文件专门为count组件生成action对象
*/

import { INCREMENT, DECREMENT } from "./constant"

//完整写法
// function createIncrementAction(data) {
//   return {type:'increment', data }
// }

//简写形式
export const createIncrementAction = data =>( {type:INCREMENT, data })

//完整写法
// function createDecrementAction(data) {
//   return {type:'decrement', data}
// }

export const createDncrementAction = data =>( {type: DECREMENT, data })

constants.js

/*
 该文件是用于定义action对象中的type类型的常量值
 目的只有一个:防止程序员在编码的同时单次写错
*/

export const INCREMENT = 'increment'

export const DECREMENT = 'decrement'

Complete code example

store.js

/*
  该文件专门用于暴露一个store对象,整个应用只有一个store对象
*/

//引入createStore,专门用于创建redux中最为核心的store对象
import {createStore} from 'redux'

//引入为Count组件服务的reducer
import countReducer from './count_reducer'

export default createStore(countReducer)

countReducer.js

/*
  1.该文件用于创建一个为count组件服务的reducer,reducer的本质就是一个函数
  2.reducer函数会接到两个参数,分别是之前的state(状态)和action(动作对象)
*/
import { INCREMENT, DECREMENT } from "./constant";

const initState = 0
export default function countReducer(preState=initState, action) {
  console.log(preState, action);
  //从action对象中获取type, data
  const {type, data} = action
  //根据type类型决定如何加工
  switch (type) {
    case INCREMENT:// 如果是加
     return preState + data
    case DECREMENT:// 如果是减
      return preState - data
    default:
      return preState
  }
}

constant.js

/*
  该文件是用于定义action对象中的type类型的常量值
  目的只有一个:防止程序员在编码的同时单次写错
*/

export const INCREMENT = 'increment'
export const DECREMENT = 'decrement'

count_action.js

/*
  该文件专门为count组件生成action对象
*/
import { INCREMENT, DECREMENT } from "./constant"
//完整写法
// function createIncrementAction(data) {
//   return {type:'increment', data }
// }
//简写形式
export const createIncrementAction = data =>( {type:INCREMENT, data })

//完整写法
// function createDecrementAction(data) {
//   return {type:'decrement', data}
// }
export const createDncrementAction = data =>( {type: DECREMENT, data })

count-index.jsx

import React, { Component } from 'react'
//引入store,用于获取redux中获取的状态
import store from '../../redux/store'
//引入actionCreator,专门用于创建action对象
import { createIncrementAction, createDncrementAction} from '../../redux/count_action'

export default class Count extends Component {
  state = {carName:'奔驰c63'}//  把状态交给reducer之后组件也可以有自己独用的状态

  increment = () => {
    const {value} = this.selectNum
    store.dispatch(createIncrementAction(value*1))
  }
  decrement = () => {
    const {value} = this.selectNum
    store.dispatch(createDncrementAction(value*1))
  }
  incrementOdd = () => {
    const {value} = this.selectNum
    const count = store.getState()
    if(count % 2 !== 0) {
      store.dispatch(createIncrementAction(value*1))
    }
  }
  incrementWait = () => {
    const {value} = this.selectNum
    setTimeout(() => {
      store.dispatch(createIncrementAction(value*1))
    }, 1000)
  }
  render() {
    return (
      <div>
        <h1>当前求和为:{store.getState()}</h1>
        <select ref={c => {this.selectNum = c}}>
          <option value="1">1</option>
          <option value="2">2</option>
          <option value="3">3</option>
        </select>&nbsp;
        <button onClick= {this.increment}>+</button>&nbsp;
        <button onClick= {this.decrement}>-</button>&nbsp;
        <button onClick= {this.incrementOdd}>当前求和为奇数再加</button>&nbsp;
        <button onClick= {this.incrementWait}>等一等再加</button>
      </div>
    )
  }
}

code structure

Guess you like

Origin blog.csdn.net/xiaojian044/article/details/128354862