Redux

Basic concept

  • Warehouse store:
  • Reducer: Processor
  • State of the state:
  • Dispatch a function.
  • Action: must be an object
  • Scbscribe: subscription

The role of the story

In order to solve the problem of state data management

Redux solves the problem

  • In React, data flows in one direction through components
  • If there are parent components between components, the data is passed from parent to child (via props)
  • Communication between components that are not parent-child (or sibling) is troublesome, so Redux takes care of the problem

Redux design idea

  • The entire state is stored in a repository, called a store
  • It stores the state tree, the state tree
  • A component can dispatch actions to a store without notifying other components directly
  • Other components can refresh their views by subscribing to state in the Store

Redux’s three principles

The three principles

  • Single data source
    • All objects exist in a single store
    • All data is stored in one object
  • State is read-only
    • The way to change the data in state is to trigger an action. “Action is a JS object.”
  • Use pure functions to perform modifications
    • Pure functions: have no effect outside the scope
    • Reducer is just a pure function that receives the previous state and action and returns the new state
    • Dispacth is implemented by the reducer

action

  • The way to change the data in state is to trigger an action. “Action is a JS object.”
  • The nice thing about using action to describe all the changes is that you can clearly see what’s going on in your application. Okay

createStore

  • Create a store through createStore, where a Reducer function is passed through createStore
  • Reducer is a pure function that updates state based on action({type: ‘XXX ‘, custom property name:’ XXX ‘})
  • parameter
    • Reducer: Processor, function type
      • Parameter 1: the old state
      • Parameter 2: action: distributed action
    • Initial state: object

Properties and methods in store

subscribe

  • Register a listener with subscribe(listener)
    • After the data update is complete, the callback function executes
    • Listeners = [];
    • Each subscribe execution puts an event in the event pool
    • Subscribe return value execution removes the current event “Filter Removed: Listeners. Filter (item=>item!==f)”
  • Unsubscribe the listener via a function returned by subscribe(listener)
  • Call the SUBSCRIBE method in store to perform setState during the componentDidMount life cycle to update the view
  • The subscribe argument is a function and the return value is a function
    • Return value execution removes the current event “executed in componentWillmount hook.”

GetState: Obtains the state

  • Provide the getState() method to get the state
    • Trigger getState when the page is loaded, there may be an error, state is undefined, therefore, need to actively trigger a dispatch({})
    • When dispatch is executed, reducer is executed, and the reducer function is executed, state avoids undefined values

Dispatch: Provides the Dispatch (Action) method to update the state

  • Data update operation
  • After the data is updated, the methods in the event pool are called
listeners.forEach(item= >{
	item&&item();
})
Copy the code

actionCreators

  • You can distribute an actionCreators function
  • That is, wrap the object passed to the Action at Dispatch into a function that returns the object
  • Reduce concatenation of objects in Dispatches
// Create actionCreator
const actions = {add, minus}
Copy the code

bindActionCreators

  • Store. Dispatch is omitted
  • Parameter 1: Actions
  • Parameter 2: Dispatch
const actions = {add, minus};// add, minus is the name of the encapsulated function
const boundActions = bindActionsCreators(actions, store.dispatch);
Copy the code

CombineReducers: Merge reducer

  • There is only one Reducer and only one repository in REdux, and the Reducer has only one state, which is difficult to maintain
  • Each component has a Reducer
  • Each component also has a corresponding action action
  • There is no need to pass default values later when creating the repository
  • If there are multiple reducer, merge the Reducer using combineReducers
  • CombineReducers performs all reducers through the for loop
    • When we execute dispatch, he will execute all reducer
    • If multiple methods are duplicated in the Reducer, all methods are executed
      • A number of reducer general projects need to be split into a separate file
    • Duplication can cause unexpected errors, so create a separate constant JS file
    • Export const CHANGE = “CHANGE”; export const CHANGE = “CHANGE”; export const CHANGE = “CHANGE”;
let rootReducer = combineReducers({
  qqq: CountReducer,
  aaa: ColorReducer
})
let store = createStore(rootReducer);
Copy the code

React-redux

Provide:

  • Receive the Store property and pass it down
  • Wrap the root component with the Provider component and pass the Provider a store that corresponds to the store generated by createStore
  • The root component is wrapped so that both its root component and its descendants can use the data in the Store

Connect: High-level component

  • It’s responsible for associating the repository with the component and getting the store from the context
  • There is no need to import the warehouse manually
  • There is no need to manually bind the action
  • Connect “is just a higher-order component” processing
    • New component = connect(callback function 1, callback function 2) (name of component to process)
      • When rendering, all new components are rendered
    • The return value of callback 1 and callback 2 must be an object whose properties are eventually passed to the component being processed
    • The callback function 1 takes a state argument
      • This is a mapping function that maps the state of the repository into separate states, which become component property objects
      // counter: component name
      mapStateProps = state= >state.counter
      Copy the code
    • The callback function 2 accepts a dispatch argument, which can be ignored
    • If there is only one callback function, you can use this.props. Dispatch to update the data
    • The finished component can be retrieved from the two callback functions via props
  • Any descendant component that wants to use the data in REdux needs to use CONNECT

redux-thunk

Solve receiver function

  • Action must be an object, or an error if it is a function
  • So we need middleware: redux-thunk, to solve the receiving function error message

Resolving the Synchronization Process

  • action -> reducer
    • After dispatch action, the reducer is directly reduced to perform the corresponding action, which is equivalent to a synchronous operation
    • If we want to implement asynchronous operations, we need to introduce middleware to change the flow of redux synchronous execution
  • action -> middewares -> reducer
    • For example, clicking the button is equivalent to dispatch to trigger action, followed by middleware to obtain the execution of server data middleware. When the middleware successfully obtains the server, it triggers the corresponding actions of reducer to update the data of the rendering view
  • Middleware mechanisms allow us to change the data flow to implement functions such as asynchronous action, action filtering, logging, exception reporting, and so on

Hooks

useDispatch

  • In the function component, get the store.dispatch method
/ / introduction
import {useDispatch} from 'react-redux'
let dispatch = useDispatch();// store.dispatch
let state = useSelector(state= >state.counter)// Get the status
/ / use
dispatch({type: 'xxx'})
Copy the code

useSelector

  • Using a selector

connected-react-router

  • Redux is a library that links redux and routing together
    • You can jump to a path by sending action
    • You can get the latest path information in the repository: Store stores location actions

Method of use

  • Create a history file
import {createBrowserHistory} from 'history'
let history = createBrowserHistory();
export default history;
Copy the code
  • Create store repository
  • Introduction: ConnectedRouter
    • ConnectedRouter requires a store in context, so use the Provider in React-Redux
  • Properties: the history = {history}
  • Wrap the root component and pass the parameter:
<Provider store={store}>
	<ConnectedRouter history={history}>.</ConnectedRouter>
</Provider>
Copy the code