Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What is the principle and usage of the various state managers of React

2025-02-23 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

Today, I will talk to you about the principle and usage of the various state managers of React, which may not be well understood by many people. in order to make you understand better, the editor has summarized the following contents for you. I hope you can get something according to this article.

First of all, we need to know what the state manager is and what it does.

When we use the same properties in multiple pages, we can use the state manager to store these states in a separate external file, which can be easily obtained whenever we want to use them.

React is a little different from vue in that react does not have its own way of state management. It actually uses the js-related state manager. What we need to keep in mind is that the view can cause a state change, and the state change will lead to the second rendering of the view.

After talking for a long time, how exactly do we use the state manager in react?

Redux makes a brilliant debut.

Redux's predecessor technology is flux, he and flux are very similar, but not exactly the same. Both stipulate that the update logic of the model is all concentrated in one level (reducer in store,redux in Flux); but there is no concept of dispatcher in redux, it relies on pure functions to do event handlers; and redux does not go back to modify your data, it will return a new object to update the state state.

First, let's take a look at some of the attributes in redux.

1 、 store:

The place where the data / state is saved can be thought of as a container. Remember that there can only be one store in the whole application

Import {createStore} from 'redux'const store = createStore (fn)

2 、 state:

You can think of state as an instance object of store, which contains all the states in the state manager and is a collection of all data / states at a certain point in time

Const state = store.getState ()

3 、 action

One of the most important attributes in redux. The only way to modify the store state is to submit an action;action is an object with a type attribute, usually this type attribute is used as the key value of the submission

Const action = {type: 'ADD_TODO', payload:' Learc Redux' / / the payload here is passed as a parameter and can be left unwritten}

4. Store.dispatch ():

The only way to submit an action is by submitting the action to the state manager, which boils down to this no matter what other state management tools you use later.

Store.dispatch ({type: 'ADD_TODO'})

5 、 reducer:

After receiving the action, store must return a new state so that the view will change, and the calculation process of this state is called reducer.

Reducer is a function that accepts the current state and action and returns a brand new state

Const reducer = (state = {count: 10 / / set the initial value for the property in state, because the state manager is emptied after each refresh, we can get the last stored value locally as the initial value}, action) = > {switch (action.type) {case 'REDUCE': / / here we can see that we look for it according to the action type value as the key value, when dispatch According to the judgment of these key values, we can find the operation return {... state, count: state.count-action.payload} / / We return a new state object on the basis of the original state according to the needs of action, without modifying the original state case 'ADD': return {... state, count: state.count + action.payload} default: return state. }} export default reducer

You can see that the way we return the new state object is through the Syntax, doesn't this approach look a little complicated, a little bit low? So let's introduce a new way, first introducing immutable components.

In this way, js actually implements a deep copy, which makes a deep copy of the original state object, so that any changes to the new state object will not affect the original state.

Yarn add immutable-S

Mode of use:

Import {Map} from 'immutable' / / introduce Map function const user = (state = Map ({/ / Deep copy of state isLogin: localStorage.getItem (' isLogin') using Map = = 'true', token: localStorage.getItem (' token') | |', adminname: localStorage.getItem ('adminname') | |', role: localStorage.getItem ('role') * 1 | | 1}) Action) = > {switch (action.type) {case 'CHANGE_LOGIN_STATE': return state.set (' isLogin', action.payload) / / set writes case 'CHANGE_TOKEN': return state.set (' token', action.payload) case 'CHANGE_ADMIN_NAME': return state.set (' adminname', action.payload) case 'CHANGE_ROLE': return state.set (' role') Action.payload) default: return state} export default userstate = > {return {adminname: state.getIn (['user',' adminname']), / / get the value by get Parameter is the meaning of this form / / first parameter: / / second parameter meaning in user state manager: status / property named adminname}}

6. Design status Manager

First of all, according to the idea of modular development, we can design multiple category state managers in a project, and finally merge them into one; for example, the status of goods, the status of user information.

Import {createStore, combineReducers} from "redux"; / / this combineReducers method is the key to modular development. It helps us merge all the sub-module state managers together import pro from'. / modules/pro'import app from'. / modules/app' const reducer = combineReducers ({/ / centralize all the reducer created by the sub-module here reducer pro, app}) const store = createStore (reducer) export default store to help with the interpretation phase

One thing we need to know is that when we want to get or modify the state at some point in time, the state manager store will generate a state instance object for us, which we can manipulate. The change in state will cause a change in the view of View, but because users do not have access to state, they can only access View, so the change in state must also be caused by View! The action is actually a notification from view, and when the user modifies the view, it will send out this notification, telling the program that the state needs to change.

/ / We can understand that the relationship among dispatch,action,store can be regarded as post office, mail and recipient.

/ We want to send a letter (action) to tell a friend (recipient) that we have found a job and need help through the dispatch; when the post office helps us deliver the mail to the recipient, the recipient will get the message I want to convey and will respond to the change.

/ / when we call dispatch, we use type (key value) to find the corresponding mail and send it to store

How is the status manager used? / / you can 'link' the status manager in the component through provider and connect After the link is successful, you can use the states and methods in the state manager / / src/xxx/index.jsximport {connect} from 'react-redux' function App (props) {.} export default connet (mapStateToProps) MapDispatchToProps) (App) / / index.jsimport {Provider} from 'react-redux'import App from'. / App.jsx'import store'. / store/index.js' ReactDom.render () / / you can also use the high-order function @ connect @ withRouter / / to fetch the corresponding data from the state tree. Let it be passed to the component via props using the connect () method included with react-redux class Home extends React.Component {/ /....} export default connect (state = > ({todos: state.todos})) (Home) / / if you use the decorator, it seems to be less complicated @ connect (state = > ({todos: state.todos})) class Home extends React.Component {/ /....}

Here we explain this approach:

To link to the state manager, we first introduce the state store into the entry file index.js of the entire project, and pass store as a parameter to the subcomponents through Provider, similar to the way ancestral components pass values to descendant components

Second, we want to connect through a higher-order function, connect, in a component that uses the state manager, which works by passing in a function as an argument and returning another function

MapStateToProps:

As can be seen from the name, we can get the state from the props parameter value in the functional component by traversing the state in state and putting it into props.

MapDispatchToProps:

Save the commit method in the state manager to props so that we can modify the state in the state manager in the component.

Const App = (props) = > {/ / the state props.adminname props.count props.bannerList props.reduceFn in the state manager can be accessed directly through props in the component.} export default connect (/ / you can see that here are two functions passed in Return two functions state = > {return {adminname: state.getIn (['user',' adminname']), / / this is a way to store state. We will talk about count: state.app.count, / / the parameter is state. We pass the count attribute in the app state manager to count bannerList: state.pro.bannerList,}} in props, and dispatch = > {return {reduceFn () {/ / We define a reduceFn here, which is the method of dispatch. In props, we can send 'REDUCE' submitted message dispatch ({type:' REDUCE', payload: 5 / / payload as a parameter, may not be passed})}) (App) through the reduceFn method

In addition to using this basic way to modify state accidents, we can also use some tools

Redux-thunk 、 redux-saga

Use of redux-thunk / / introduce thunk in store.js and mount it to the state manager import {createStore, combineReducers, applyMiddleware} from 'redux' import thunk from' redux-thunk'import app from'. / modules/app'import pro from'. / modules/pro' const reducer = combineReducers ({app, pro}) / / Mount thunk to the state manager const store = createStore (reducer, applyMiddleware (thunk) export default store via applyMiddleware

Then we design a separate file to encapsulate the modified state, including asynchronous mode

/ /... / store/actionCreator/pro.js / / this file is specifically used to trigger asynchronous operations / / when the thunk module executes, the actionCreator function has a default parameter of dispatch//. The dispatch can be used to trigger reducer//. Sometimes parameters need to be passed when triggering async. You can return an actionCreator function inside the function const actions = {getBannerListAction (dispatch) {fetch ('http://121.89.205.189/api/banner/list'). Then (res = > res.json ()). Then (res = > {dispatch ({type:' CHANGE_BANNER_LIST', payload: res.data})})}, getProListAction (count) {/ / has parameters Returns a function The function parameter defaults to dispatch count = count | | 1 return function (dispatch) {fetch ('http://121.89.205.189/api/pro/list?count=' + count). Then (res = > res.json ()). Then (res = > {dispatch ({type:' CHANGE_PRO_LIST', payload: res.data})}} export default actions

Think of the above steps as defining an action object with some dispatch submitting the action. When we want to modify the state in the component, we can directly use the function in this object. The function will automatically initiate the request and submit the action.

As can be seen from the use in the following components, we dispatch (actions.getBannerListAction); it is actually the form of submitting aciton, but we encapsulate action modifications and asynchronous requests.

Import actions from'. / store/actionCreator/pro'const App = (props) = > {/ / props can be accessed directly to props.reduceFn () props.addFn () props.getBannerList () props.getProList ()} const mapStateToProps = (state) = > {return {count: state.app.count, bannerList: state.pro.bannerList ProList: state.pro.proList}} const mapDispatchToProps = (dispatch) = > {return {reduceFn () {/ / modify status dispatch ({type: 'REDUCE', payload: 5})}, addFn () {dispatch ({type:' ADD', payload: 5})} GetBannerList () {/ / modify status dispatch (actions.getBannerListAction)} through thunk, getProList () {dispatch (actions.getProListAction (2))} export default connect (mapStateToProps, mapDispatchToProps) (App)

The way of linking is exactly the same as that of ordinary react-redux, and finally, the state is modified by dispatch and action.

The use of react-saga

Install redux-saga

Yarn add redux-saga immutable redux-immutable-S

We can think of redux-saga and redux-thunk as a way to send dispatch. In the old days, we sent dispatch by car or on foot. Using tools can be seen as sending mail by bullet train or plane.

Import {createStore, combineReducers, applyMiddleware} from 'redux' import createSagaMiddleware from' redux-saga' import mySaga from'. / mySaga' / / Asynchronous Operation instructions import home from'. / modules/home'import app from'. / modules/app' const reducer = combineReducers ({app, home}) const sagaMiddleware = createSagaMiddleware () / / generate saga middleware const store = createStore (reducer, applyMiddleware (sagaMiddleware) / / establish links / / same as thunk By mounting the saga middleware to the state manager, you can use saga to modify the state. SagaMiddleware.run (mySaga) / / run: send / / here encapsulates a mySage function as the function export default store to modify the state. Next, we will describe in detail how saga modifies the state.

In redux-saga, the Genarator function is used to modify the state

Import {call, put, takeLatest} from 'redux-saga/effects' import {getBannerList, getProList} from'. / api/home' / / redux-saga-- > must be used with the generator function function * getBannerListAction () {const res = yield call (getBannerList) / / call-- call function yield put ({type: 'CHANGE_BANNER_LIST', payload: res.data})} function * getProListAction (action) {const res = yield call (getProList) Action.payload) yield put ({type: 'CHANGE_PRO_LIST', payload: res.data})} function * mySaga () {yield takeLatest (' REQUEST_BANNER_LIST', getBannerListAction) yield takeLatest ('REQUEST_PRO_LIST', getProListAction)} export default mySaga

If you can't read it, don't be afraid. Look at here

In the / / mysaga file, we define the way to send import {takeLatest} from 'redux-saga/effects'// takeLatest-assign tasks; below. We defined key ourselves and assigned events to it. These events are function * getProListAction (action) {const res = yield call (getProList, action.payload) yield put ({type: 'CHANGE_PRO_LIST', payload: res.data})} function * mySaga () {yield takeLatest (' REQUEST_PRO_LIST') used by the store.dispatch () function. GetProListAction)} / / We don't need to use store.dispatch () when we want to modify the state later. / / We can use the key value defined in this file to modify / / We define the custom function in the connect of the component. Call the modification method dispatch = > {dispatch ({type: 'REQUEST_PRO_LIST'})} / / put directly according to the key value. Call// call-- > means to call / / put-> means to push, push the current action to the next (queue). Yield put (action) yield call (fn) after reading the above, do you have any further understanding of the principle and usage of the various state managers of React? If you want to know more knowledge or related content, please follow the industry information channel, thank you for your support.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report