Problems encountered when Redux is not used in React

In React, the data flow between components is one-way. The top component can transfer data to the lower layer through the props property, while the lower layer component cannot transfer data to the upper layer component. To enable the lower layer component to modify data, the upper layer component needs to transfer the data modification method to the lower layer component. As projects grow larger, it becomes more difficult to pass data between components.

The benefits of adding Redux to the React project

Using Redux to manage data, since Store is independent of component, makes data management independent of component, solves the problem of passing data from component to component.

React + Redux

Download the story

npm install redux react-redux
Copy the code

Review the Redux workflow

  1. The component triggers an Action through the Dispatch method
  2. The Store receives the actions and distributes them to the Reducer
  3. Reducer changes the State based on the Action type and returns the changed State to State
  4. The component subscribes to state in the Store, and state updates in the Store are synchronized to the component

Steps to use Redux

1. Create a Store and Reducer
  • Create a Store and Reducer

The createStore method is used to create a Store, and the return value of the method is Store. The createStore method needs to be imported from Redux

  • The first parameter of the createStore method needs to be passed to the Reducer
  • Reducer is a function, what the function returns, what is stored in the store, the function name is customized
import { createStore } from 'react';

function reducer () {
  return { count: 1 };
}
const store = createStore(reducer);
Copy the code
2. The component obtains data from the Store
  • Put the data from the Store into the Provider component, which stores the shared data.
import { Provider } from 'react-redux';
ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>
);
Copy the code
  • The component subscribes to the data using the CONNECT method, gets the data, and passes the data to the component via props
import { connect } from 'react-redux';
const mapStateToProps = state= > ({
  count: state.count
})
export defaultConnect (mapStateToProps)(component name);Copy the code

3. The component changes the data in Store
  1. Define the action
{ type: 'Describe what to do with the data' }
Copy the code

Action is the only way to change the state

  1. Component triggers action
this.props.dispatch({ type: 'Describe what to do with the data' })
Copy the code
  1. Reducer receives the action, processes the data against the action and returns it
const initialState = { count: 0 };
const reducer = (state = initialState, action) = > {
  awitch (action.type) {
   case 'Describe what to do with the data':
     return { count: state.count + 1 };
   dafault:
     returnstate; }}Copy the code
4. Pass parameters for action
  1. Passing parameters
<button onClick={() = > increment(5> +)}5 </button>
Copy the code
  1. Receive the parameters and pass reducer
export const increment = payload= > ({ type: INCREMENT, payload });
Copy the code
  1. Reducer processes the received data
const reducer = (state = initialState, action) = > {
  awitch (action.type) {
   case 'Describe what to do with the data':
     return { count: state.count + action.payload };
   dafault:
     returnstate; }}Copy the code

To optimize the

Use the Action Creator function to separate the code that triggers the Action into a function

Action is triggered in the component template by calling this.props. Dispatch ({type: ‘Describe what to do with the data’}).

const mapDispatchToProps = dispatch= > ({
  increment () {
    dispatch({ type: 'increment'})
  },
  decrement () {
    dispatch({ type: 'decrement'})}})export defaultConnect (mapStateToProps, mapDispatchToProps)(component name);Copy the code
The Action Creators function is bound

Functions that trigger actions have a very high rate of code duplication, so React provides a way to generate those functions instead of writing them by hand

// store.actions.couter.aciton.js
export const increment = () = > ({ type: 'increment' })
export const decrement = () = > ({ type: 'decrement' })
/ / component
import { bindActionCreators } from 'redux';
import * as counterAction from '.. /store/actions/counter.action.js';
const mapDispatchToProps = dispatch= > ({
  ...bindActionCreators(counterActions, dispatch)
})
Copy the code
Isolate the Action type string as a constant

The Action string component needs to be used when Action is triggered, and the Reducer needs to use it when Action is received. Since there is no code prompt for the string and there is a risk of writing errors, it is independent as a constant.

Split Reducer

As more and more data is to be managed, the code in the Reducer will become larger and larger. Redux allows a large reducer to be divided into several small reducers, which are finally combined and used.

import { combineReducers } from 'redux';

export default combineReducers ({
  counter: counterReducer,
  modal: modalReducer
})
Copy the code

Get the data after splitting

import { connect } from 'react-redux';
const mapStateToProps = state= > ({
  count: state.counter.count
})
export defaultConnect (mapStateToProps)(component name);Copy the code