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.
redux
Is a special for doingState managementtheJS
Library (not react plugin library)- Function: Centrally manages the state shared by multiple components in react references
A,redux
The 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 mandatorydata
: Data attribute. The value type is arbitrary and optional
Second,redux
The use of
-
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 of
createStore
, which is used to createredux
The core store object in - Introduced to serve the Count component
reducer
- exposed
store
object
import { createStore } from 'redux' import countReducer from './count_reducer' export default store = createStore(countReducer); Copy the code
- The introduction of
-
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
-
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
-
When store.dispatch is called in the component, pass the value and time to the action,
store.dispatch(createIncrementAsyncAction(value, 500)) Copy the code
-
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 a
npm add redux-thunk
Library, introducing Thunk in store, - At the same time in
redux
To introduce one moreapplyMiddleware
- Exposure to store:
export default createStore(countReducer, applyMiddleware(thunk));