This is the 11th day of my participation in the August More Text Challenge. For details, see:August is more challenging

redux

When learning React, the parent component was used to pass state between sibling components. Redux solves this problem by making the state of one component readily available to other components. Redux is used when one component needs to change the state of another component. But because the implementation of Redux is more complicated, if you can not use it, but still need to learn.

  • reduxIs a special for doingState managementtheJSLibrary (not react plugin library)
  • Function: Centrally manages the state shared by multiple components in react references

A,reduxThe working process

Components can distribute tasks and pass previous state values to Reducers for processing. Reducers will initially initialize the state and then process the state. During processing, new pure functions will be generated according to the old state and action, and after processing, the new state values will be returned to Store and then passed to the component. Here, the store is an important object that connects state, action, and Reducer.

Action (object for action)

  • type: Identifies the property. The value is a string, unique and mandatory
  • data: Data attribute. The value type is arbitrary and optional

Second,reduxThe use of

  1. Create a Store

    Create a redux folder in SRC and a store.js folder inside. This file is specifically used to expose a store object. There is only one store object for the entire application

    • The introduction ofcreateStore, which is used to createreduxThe core store object in
    • Introduced to serve the Count componentreducer
    • exposedstoreobject
    import { createStore } from 'redux'
    import countReducer from './count_reducer'
    export default store = createStore(countReducer);
    Copy the code
  2. If you have the Store, you must also have the Reducer

    Create a reducer. Js file in redux. This file is used to create a reducer for a component. The reducer function receives two parameters: the previous state (preState) and the action (action); Reducer has two functions: initialization state and processing state

    Initialize the state when the initial state value is undefine or null; Then we get the type and data from the Action object. We use the switch to handle the different types.

    const initState = 0;
    export default function countReducer(preState = initState, action) {
        const { type, data } = action;
        switch (type) {
            case 'increment': return preState + data
            default: return preState
        }
    }
    Copy the code
  1. Create an actionCreator. Js file in redux to create actions to be taken. Create an Action object for the component. Such as:

    export const createIncrementAction = data= > ({ type: 'increment', data })
    Copy the code

If there are many types of methods, you can create a file to define the variable names of these methods to prevent errors. It is also easy to manage. Example: export const INCREMENT = ‘INCREMENT ‘;

Import the store.js file you just created into the component, and use store.getState to get the state stored in redux.

// Just react
increment = () = > {
    const { value } = this.selectNumber;
    const { count } = this.state;
    this.setState({ count: count + parseInt(value) })
}
// Add after redux
increment = () = > {
    const { value } = this.selectNumber;
    store.dispatch(createIncrementAction(value))
}
Copy the code

If this function is called, the state changes, but in Redux, it just manages the state, it doesn’t update the page; Therefore, we need to manually call Render () here, so we need to use a lifecycle hook — componentDidMount — that detects state changes in redux and calls render whenever they happen

componentDidMount() {
    store.subscribe(() = > {
        this.setState({})
    })
}
Copy the code

To avoid the inconvenience of writing this code in each component if implemented with lifecycle hooks, you can also include a subscription function in the render App component’s index.js.

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

Asynchronous action

A synchronous action returns an object, while an asynchronous action returns a function. In the case of synchronization, the timer is written in the method of the component. In the case of asynchronous, the timer is written in the method

  1. When store.dispatch is called in the component, pass the value and time to the action,

    store.dispatch(createIncrementAsyncAction(value, 500))
    Copy the code
  2. Call the timer in the action;

    export const createIncrementAsyncAction = (data, time) = > {
        return () = > {
            setTimeout(() = > {
               dispatch({ type: INCREMENT, data }) }, time); }}Copy the code
  • Because a store can only receive an object, not a function
  • Download anpm add redux-thunkLibrary, introducing Thunk in store,
  • At the same time inreduxTo introduce one moreapplyMiddleware
  • Exposure to store:export default createStore(countReducer, applyMiddleware(thunk));