One, foreword

React-navtive state management requires redux. The following is a flowchart of how redux works

If the React component wants to change its state,

  1. You need to make the callActionCreatorsCreate an Action object,
  2. Then call store.dispatch(the action object),
  3. Store passes (previousState, Action) to the Reducers, which returns newState,
  4. The Store updates the state to the React component

I’m going to the library to borrow a book

  1. ActionCreatorsCreate a statement: What book do I need to borrow?
  2. The librarian (Store) receives my request (dispatch(action object))
  3. The librarian enters the request (previousState,action) into the Reducers of the computer. When the Reducers are finished, the new Reducers are returned
  4. The librarian gave me the React Component book (state)

Two, installation environment

npm install --save redux
npm install --save react-redux
npm install --save-dev redux-devtools
Copy the code

Redux (Required)

React-redux (Required)

Redux-devtools (optional) Redux developer tools support hot loading, action replay, and UI customization

3. Create corresponding files

├ ─ ─ store │ ├ ─ ─ reducer. Js │ ├ ─ ─ actionCreator. Js │ ├ ─ ─ index, jsCopy the code

Create the store

// store/inde.js
import {createStore} from "redux"
import reducer from "./reducer"
const store = createStore(reducer)
export default store
Copy the code

Create the reducer

// store/reducer.js const defaultState = { token:"" } export default (state=defaultState,action)=>{ if(action.type==="token"){ let newState = {... state} newState.token=action.value return newState } return state }Copy the code

Create constants

// store/constants.js
export const TOKEN = "token"
Copy the code

Create actionCreator

// store/actionCreator
export const setToken =(token){
  return {
    type:"token",
    value:token
  }
}
Copy the code

4. Component acquisition and change state

Access to the state

import store from './store/index'
class demo extends Component{
  constructor(props){
  	super(props);
    	this.state = store.getState()
   }
   render(){
    	return (
        	<View>{this.state.token}</View>
        )
  }
}

Copy the code

Change the state

import {setToken} from "./store/actionCreators" import store from './store/index' class demo extends Component{ constructor(props){ super(props) } changToken = (token)=>{ const action = setToken(token); // Create the action object store.dispatch(action); } to render () {return (< Button title = "set the Token" onPress = {() = > {enclosing changeToken (" ABC ")}} / >)}}Copy the code

5. Use the third-party library Redux-Thunk

Native Redux can only handle state synchronously. When we want to handle state asynchronously, there is no way to do so. For example, when the user sends a login request, the server will return the token, so we need to store the token in state. So we need to use redux-thunk, which can change state asynchronously

The installation

npm install --save redux-thunk
Copy the code

Use the Redux-Thunk middleware when creating stores

// store/index.js
import { createStore, applyMiddleware } from 'redux';
import thunk from "redux-thunk"
import reducer from "./reducer"
const store = createStore(reducer,applyMiddleware(thunk))
export default store
Copy the code

Create asynchronous functions in actionCreator

// store/actionCreators import {login} from ".. / API /login"//login is a network request for login export const setToken = (token)=>({type:"token", value:token }) export const Login = ({phone,password})=>{ return dispatch=>{ login({phone,password}).then(res=>{ if(res.code==200){ const action = setToken(res.data) dispatch(action) } }) } }Copy the code

Invoke asynchronous functions in the component

import {Login} from ".. /store/actionCreators" import store from ".. /store" class demo extends Component {render(){return <View onClick={this.handlelogin}> </View>} handLogin=()=>{ Const action = Login({phone:1234,password:1234}) store.dispatch(action)}}Copy the code

View component binding

  • <Provider>Component: This component needs to be wrapped around the outermost layer of the component tree. This component makes it easy for all of its descendants to useconnect()Method bind store
  • connect()React-redux: This is a method provided by the react-redux to pass itself as a parameter if a component wants to respond to changes in stateconnect()The connect() method handles the details of the bind to the store and determines which part of the bind store’s data by selector
  • selectorThis is a function you write that declares what part of the store your component needs as its props
  • dispatchWhenever you want to change state in your application, you dispatch an action, which is the only way to change state

React-redux provides the following apis

  • Provider
  • connect

Provider

In order to use conect() globally, the root component must be nested within

import {Provider} from "react-redux"
import store from "./store"
function App(){
  return(
    <Provider store={store}>
      <AppIndex></AppIndex>
    </Provider>
  )
}
Copy the code

connect

Connect ([mapStateToProps],[mapDispatchToProps],[mergeProps],[options])

React-redux provides a connect function. Connect is a higher-order function that is passed in as mapStateToProps, mapDispatchToProps, and wrapWithConnect, which produces the Component. Passing the real Component as an argument to wrapWithConnect(MyComponent) produces a wrapped Connect Component:

Export default connect(mapStateToProps)(HomePage)

Use CONNECT in the component

import {connect} from "react-redux" import actionCreators from ".. /store/actionCreators" class deom extends Component{ render(){ reuturn ( <View>token:{this.props.token}</View> <View OnClick ={this.props.Login({phone:1234,password:1234})}} const mapStateToProps = state=>{return { token:state.token } } const mapDispatchToProps = dispatch=>{ return { Login({phone,password}){ const action = actionCreators.Login({phone,password}) dispatch(action) } } } export default connect(mapStateToProps,mapDispatchToProps)(demo)Copy the code

The mapStateToProps function maps the state in the store to the props of the component. This.props. To Ken is used to obtain a token stored in the store

MapDispatchToProps returns an object that has a number of methods that can call Dispatch, and all of those methods are mapped to the component’s props, either through this.props. The method call

Use actionTypes

The general action object is as follows:

{
  type:"token",
  value:"1432"
}
Copy the code

In the Reducer, determine the type of the action

export default function (state=defaultState,action){ if(action.type==="token"){ .... }}Copy the code

As can be seen from the above, type is a string type. In the development process, if a string is written incorrectly, the program will run an error, but the system will not report an error. In order to solve this problem, we can change the string into a variable

You can create new actionTypes under the Store folder to store type

├ ─ ─ store │ ├ ─ ─ reducer. Js │ ├ ─ ─ actionTypes. Js │ ├ ─ ─ actionCreator. Js │ ├ ─ ─ index, jsCopy the code
// store/actionTypes
export const TOKEN = "token"
Copy the code
// store/actionCreator
import * as actionTypes from "./actionTypes"
export const setToken = (token)=>({
  type:actionTypes.TOKEN,
  value:token,
})
Copy the code
// store/reducer
import * as actionTypes from "./actionTypes"
export default (state=defaultState,action)=>{
  if(action.type===actionTypes.TOKEN)
}
Copy the code

This way, the system will warn us when we miswrite the variable name

Eight, use combineReducers

An APP may have user information, historical messages, device information and so on. If we put all the information into a reducer, it will be too bloated and difficult to manage. Therefore, we can merge multiple reducer with combineReducers provided by Redux

// store/reducer import {combineReducers} from "redux" import {reducer as UserReducer} from ".. /page/UserLogin/store" import {reducer as DeviceReducer} from ".. /page/Device/store" export default combineReducers({ user:UserReducer, device:DeviceReducer })Copy the code

This can be used in components

mapStateToProps=(state)=>{
  return {
    token:state.user.token,
    deviceNum:state.device.number
  }
}
Copy the code

conclusion

Give a rose, the hand has lingering fragrance. Everybody see officer, feel good please point a praise, if have mistake place, also please correct ah

Author: Hu Zhiwu

Time: 2020/02/13