preface

The purpose of this article is to demonstrate a simple react-Redux state manager in plain English to help you integrate the React-Redux library into your own projects.

  • If you don’t know redux library actions, Reducer, Store… For those concepts, you can learn about Redux from the documentation and then read this article
  • If you already have an in-depth understanding or use of React-Redux, this article may be too easy for you to read, so skip it
  • If you’ve only learned the basics of Redux, but don’t know how to apply react-Redux to a real project, or if you don’t understand some of the concepts in the documentation, this article will give you some inspiration
  • The demo source is available on Github (github.com/TimorCookie…). If you have any questions, you can leave a message or fork the source code directly

1. An overview of the

1.1 React and Redux

  • React is unrelated to Redux, which supports React, Angular, jQuery, and even javascript
  • Redux works better with libraries like React

1.2 the React – story

  • React-redux is the redux binding library that works with React
  • React-redux allows your React component to easily read data from the Redux store and distribute actions updates to the store

1.3 Two important members of React-Redux

  • Provider is a component that allows you to access data in the Store throughout your app
    • The Provider wraps around the component so that all child components can get state
    • The Provider receives the Store as props and passes it down through the context so that any component in react can access the Store through the context
    • Resolved that container components may have deep layers, preventing state passing layer by layer
  • Connect is a method that associates components with stores
    • Provider internal components that want to use data in state must be wrapped with Connect (must be reinforced by Connect).
    • Connect is a way for our component to get state from store

2. React-redux is used

2.1 Preparations

2.1.1 Use create-React-app scaffolding to generate projects

npx create-react-app count-demo

2.2.2 Delete unnecessary components and modify the project structure & configuration

2.2 install the react – story

  • React-redux is not officially provided by React, so it will need to be installed after we build the React project
yarn add react-redux
npm install react-redux --save
Copy the code
  • React-redux also relies on stores in Redux, so we also need to install Redux
yarn add redux
npm install redux --save
Copy the code

2.3 Use Redux to build stores

  • Create a reducer/index.js file and build the reducer to respond to actions
/ / reducer/index. Js / * * * @ desc pure functions, receives two parameters * @ paream state * @ paream action /export const reducer = (state, action)=> {
    return state
}
Copy the code
  • Create a store/index.js file and pass in our reducer using the createStore method
// store/index.js
import { createStore } from 'redux'
import { reducer } from '.. /reducer'

const store = createStore(reducer)
export default store
Copy the code
  • Introduce store in app.js
// app.js
import React from 'react'
import "./App.css"// Import our storefunction App() {
    return <div className="App"><div/>
}
Copy the code

2.4 Building a Page

  • Implement a counter that can handle addition and subtraction, as shown in the following figure

  • Create a component called CountButton with two button buttons in it
// components/CountButton.jsx
import React from 'react'

export default function CountButton() {
  return (
    <button> +10 </button>
    <button> -2 </button>
  )
}
Copy the code
  • Create another component with the name CountNum and put a div inside it to visualize the number
// components/CountNum.jsx
import React from 'react'

export default function CountNum(props) {
  return (
    <div>0</div>
  )
}
Copy the code
  • Two components are introduced in app.js
// app.js
import React from 'react';
import './App.css';

import store from './react-redux/store'
import CountButton from './components/CountButton'
import CountNum from './components/CountNum'
function App() {
  return (
    <div className="App">
      <CountButton />
      <CountNum />
    </div>
  );
}

export default App;
Copy the code

2.5 Action and Reducer transformation

  • Action create function
    • Action is the payload for transferring data from the app to the Store; It is the only source of store data.
    • Actions are essentially JavaScript ordinary objects. We agree that an action must use a type field of type string to indicate the action to be performed
    • The Action creation function is the method that generates the Action
// actions/index.js
export const addAction = (num)=> {
  return {
    type: 'ADD_NUM',
    payload: {
      num
    }
  }
}

export const reduceAction=(num)=> {
  return {
    type: 'REDUCE_NUM',
    payload: {
      num
    }
  }
}
Copy the code
  • Our component has two functions of increase and decrease, so reducer needs to deal with different scenarios according to different action types.
    • Reducer specifies how do application state changes respond to actions and are sent to the store
    • Reducer is a pure function that receives the old state and action and returns the new state.
    • It is important to keep reducer pure. Never do these things in a Reducer:
      • Modify the passed parameter;
      • Perform operations that have side effects, such as API requests and route jumps;
      • Call impure functions, such as date.now () or math.random ().

Note:

Do not modify state. Create a new copy using object.assign (). You cannot use object.assign (state, {visibilityFilter: action.filter}) as this will change the value of the first argument. You must set the first parameter to empty object. You can also turn on support for the ES7 proposal object expansion operator to use {… state, … NewState} serves the same purpose. Return the old state in default. When encountering an unknown action, always return to the old state.

// reducer/index.js
const initialState = {
  count: 0
}
export const reducer = (state = initialState, action)=> {
  switch (action.type) {
    case 'ADD_NUM':
      return {
        ...state,
        count: state.count + action.payload.num
      }
    case 'REDUCE_NUM':
      return {
        ...state,
        count: state.count - action.payload.num
      }
    default:
      return state
  }
}
Copy the code

2.6 Importing the Provider Component

  • Import the Provider component in app.js
import { Provider } from 'react-redux'
Copy the code
  • Use the Provider component to wrap our entire structure
  • Set the Store property to the Provider component. This value is the store instance object constructed by createStore
function App() {
  return (
    <Provider store={ store }>
      <div className="App">
        <CountButton />
        <CountNum />
      </div>
    </Provider>
  );
}
Copy the code

2.7 the connect using

  • Import connect method
import { conenct } from 'react-redux'
Copy the code
  • Call connect method
connect(...) (Component)Copy the code

Connect Parameter Description

Parameter names type instructions
mapStateToProps(state, ownProps) Function 1. This function allows us to bind the data in the store to the component as props; 2. State: store in redux; OwnProps: props for myself.
mapDispatchToProps(dispatch, ownProps) Function 1. Bind actions as props to our own functions; ()3. OwnProps () 4. 3. There must be a return value of Object type
mergeProps(stateProps, dispatchProps, ownProps) Function To assign to the component, either the stateProps or dispatchProps method needs to be merged with ownProps. Normally, if this parameter is not passed, connect will use object. assign instead
options Function You can customize the behavior of the Connector
  • Use the Connect method to associate our component with a Store
    • Import connect methods in the components CountButton and CountNum, respectively
    • Use the CONNECT method to enhance and export our component
    • The component CountButton belongs to the sender, so the second parameter is implemented
    • The component CountNum belongs to the receiver, so you implement the first parameter

2.8 Component Implementation

2.8.1 CountButton Sends an action

  • Import the connect
  • Strengthen components with CONNECT: CONNECT (function to accept array, function to send action)(place component to strengthen)
  • You need to implement the second parameter builder function, mapDispatchToProps(Dispatch); Dispatch is used to send actions
  • This method can be called inside the component via props
// CountButton.jsx
import React from 'react'
import { connect } from 'react-redux'
import { addAction, reduceAction } from '.. /react-redux/actions'

function CountButton(props) {
  const addTen = ()=> {
    props.sendAdd(10)
  }
  const reduceTwo =()=> {
    props.sendReduce(2)
  }
  return( <> <button onClick={addTen}> +10</button> <button onClick={reduceTwo}> -2 </button> </> ) } const mapDispatchToProps =  dispatch=> {return{// Dispatch an addAction sendAdd: (num)=> {dispatch(addAction(num))}, // Dispatch a reduceAction sendReduce: (num)=> { dispatch(reduceAction(num)) } } }export default connect(null, mapDispatchToProps)(CountButton)
Copy the code

2.8.2 CountNum receive state

  • Import connect method
  • Components are enhanced with CONNECT
  • CountNum is the receiver, so we need to implement the first parameter of connect, mapStateToProps, which is the parameter we care about. Return this state to get the latest data from inside the component. The key to whether CountNum can get data is the reducer, which can be obtained only when the reducer returns a new state
import React from 'react'
import { connect } from 'react-redux'
function CountNum(props) {
  return (
    <div>{props.count}</div>
  )
}
const mapStateToProps = state => {
  return state
}
export default connect(mapStateToProps)(CountNum)
Copy the code

Reference 3.

  • Redux documentation: redux.js.org/introductio…
  • React-redux files: react-redux.js.org/introductio…
  • Redux Chinese document (amway wave, document organized a lot of practical demo can follow) : www.redux.org.cn/