Redux entry level tutorial documentation

Here I will explain Redux to you in plain English and teach you how to use Redux step by step.

I. Concept description

1. What is Redux and why do you use Redux

Redux is a JavaScript state container that provides predictable state management.

What does that mean? In other words, as a page becomes complicated, a lot of data on the page needs to be saved. If a route is redirected, the data on the previous page is destroyed, resulting in data loss.

Passing through a URL is cumbersome, passing every piece of data into a component is a mindless waste of time to write.

2. Why Redux

If there is a repository for data that needs to be retained throughout the project, and components can access the repository directly. The data will be consistent and clear all the time.

Second, environment building

1, install,

First we’ll create a React project with create-react app.

create-react-app redux-text,

Install the story:

NPM install –save redux or yarn add redux

NPM install –save react-redux or yarn add react-redux

2. Brief explanation of concepts

Here are a few concepts that you should know a little bit about:

Store: We store a warehouse for the whole project. A project can only have one warehouse to store the data that needs to be saved.

State: data saved in store.

Action: The user’s actions on the page do not change the state in the store. To change the view on the page, you need to tell the state on the page that you want to change it through action. Note: this action only tells the warehouse that the data is about to change, not to change the data!

Reducer: Receives action requests and modifies state changes in the store.

3. Directory structure

Now let’s create a few folders and files that will be used in the project. Here is the directory structure:

. ├ ─ ─. Gitignore ├ ─ ─ the README. Md ├ ─ ─ the SRC │ └ ─ ─ action │ ├ ─ ─ oneAction. Js │ ├ ─ ─ twoAction. Js │ └ ─ ─ components │ └ ─ ─ Container │ ├ ─ ─ pageOne | ├ ─ ─ index. The js │ └ ─ ─ reducer │ ├ ─ ─ oneReducer. Js │ ├ ─ ─ twoReducer. Js │ ├ ─ ─ index. The js │ └ ─ ─ App. The CSS │ ├ ─ ├ ─..... ├── Node_modules ├─ Package. json ├─ publicCopy the code

3. Build data sources

Create two data sources:

SRC/reducer/oneReducer. Js and SRC/reducer/twoReducer js

const oneReducer = (
  state = {
    name: 'navigation navigation'.address: 'the fuzhou'
  },
  action
) => {
  switch(action.type) {
    case 'setName': 
      return {
        ...state,
        name: action.payload.name
      }
    default: 
    returnstate; }}export default oneReducer;
Copy the code

The two parameters of the pure function oneReducer(state, action) represent the state and action named oneReducer in the store respectively.

State: stores all data sources and initial values under oneReducer.

Action: Perform different operations on different action. types to modify state data

Note: Redux does not change the original state each time it changes the state. Instead, it returns a new state, replacing the old state with the new state.

When action.type is setName, we first deconstruct the original state and attach a new value to name.

The same goes for tworeducer.js:

const twoReducer = (
  state = {
    age: 10,
  },
  action
) => {
  switch(action.type) {
    case 'setAge':
      return {
        ...state,
        age: 11,}default: 
    returnstate; }}export default twoReducer;
Copy the code

Finally, consolidate all the reducer

import { combineReducers } from 'redux';

import OneReducer from './oneReducer';
import TwoReducer from './twoReducer';

export default combineReducers({
  OneReducer,
  TwoReducer,
})
Copy the code

CombineReducers: Form all the sub-reducer functions into objects and provide a new reducer function

4. Write pages

Let’s write a simple page that presents the data from both sources.

1. Create a repository

Open the SRC/index. Js

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import * as serviceWorker from './serviceWorker';
import PageOne from './container/pageOne';
import { createStore } from 'redux';
import { Provider } from 'react-redux';
import Reducer from './reducer';

const store = createStore(Reducer);

ReactDOM.render(
  <Provider store={store}>
    <PageOne/>
  </Provider>
, document.getElementById('root'));

serviceWorker.unregister();
Copy the code

CreateStore: Creates a repository for all data sources under recuder.

Provider: A component provided by Redux that passes stores to its own components. Simply put, wrap a component in the outermost layer of the project and put it into a store, which binds the store into the project.

2. Display page

So now let’s focus on page/SRC/container/pageOne/index. The js code:

import React from 'react';
import { connect } from 'react-redux';

class PageOne extends React.Component {
  render() {
    const { oneReducer, twoReducer } = this.props;
    const { name = ' ', address = ' ' } = oneReducer;
    const { age = 0 } = twoReducer;
    console.log(oneReducer, twoReducer);
    return (
      <div>
        <div>name: {name}</div>
        <div>address: {address}</div>
        <div>age: {age}</div>
      </div>)}}const mapStateToProps = state= > {
  const { oneReducer, twoReducer } = state;
  return {
    oneReducer,
    twoReducer,
  }
}

export default connect(mapStateToProps)(PageOne);
Copy the code

Explain in detail the following above knowledge point ha:

MapStateToProps: Get the data source under the Store repository. Here you can print the following state to see the output.

Connect: method provided by the React Redux library that maps the current Redux store state to the presentation component props.

Connect has been optimized to avoid many unnecessary repeated renders, such as writing a shouldComponentUpdate method to update the presentation data when state data changes.

So, at this point, we can get the data in the warehouse using this.props.

3. Modify warehouse data

Store data cannot be modified, which ensures data stability. So redux throws a store.dispatch(Action) event that allows the user to modify store data.

So we continue to modify the pageOne/index.js page above (short) :

class PageOne extends React.Component {
  
  changeName = (val) = > {
    this.props.dispatch({
      type: 'setName'.payload: {
        name: val
      }
    })
  }

  render() {
    return (
      <div>
        <div>name: {name}</div>
        <div>address: {address}</div>
        <div>age: {age}</div>
        <button onClick={() = >{this.changename ('change_name')}}> Change the name</button>
      </div>)}}Copy the code

Now try the following execution button click events.

Ok, so at this point a state management operation is complete. If you are careful, you will notice that action is not used.

So what exactly does this action do?

In my understanding, that means putting the contents of the dispatch into the action.

Write actions

Write the SRC/action/oneAction. Js

export const setName = (name) = > ({
  type: 'setName'.payload: {
    name,
  }
})

export const setAge = (age) = > ({
  type: 'setAge',
  age
})
Copy the code

Modify pageOne/index.js (short) :

import { setName } from '.. /.. /action/oneAction';

class PageOne extends React.Component {
  changeName = (val) = > {
    this.props.dispatch(setName(val))
  }
  ...
}
Copy the code

Does the following work for discovery? So why do we write actions?

In my understanding: In order to pay more attention to MVC mode, View should pay more attention to the display logic of View, so the logic operation unrelated to UI is entrusted to Redux to deal with, reflecting the programming idea of code stratification and responsibility separation.

Middleware – Asynchronous

1. Code operation (the second point is the knowledge point explanation, small friends want to see ha)

Since in most cases, dispatch is not just to update reducer immediately, other functions need to be executed to meet the needs of the project, such functions are middleware. Finally, reducer is executed after a series of middleware

If we call the server interface, there is a time delay; Or I want to take other reducer operations from the Reducer as well, ok?

Let’s try it out:

Add another method to our oneaction.js file:

export const allChange = (a)= > dispatch => {
  dispatch(setName('all_hang'));
  dispatch(setAge(10010));
}
Copy the code

Add a click event (short) to pageone. js:

import { setName, allChange } from '.. /.. /action/oneAction'; class PageOne extends React.Component { changeAll = () => { this.props.dispatch(allChange()) } render() { return ( ... The < div > < button onClick = {() = > {enclosing changeAll ()}} > modify all < / button > < / div >...). }}Copy the code

We found the error when we clicked the button. Use custom middleware for async Actions. Use custom middleware for asynchronous operations.

It is ok to call other reducer methods from reducer, but because we lack middleware, we received an error. Now let’s add the middleware:

Before we modify the code we need to edit the CLI and add a new command

Yarn add redux-thunk or NPM install –save redux-thunk Import the redux-thunk library.

Edit SRC /index.js(short):

The following is shorthand code. The original content on the page is not removed, but a few lines of code have been added and the createStore has been modified

import { createStore, applyMiddleware } from 'redux';
import thunkMiddleware from 'redux-thunk';

conststore = createStore( Reducer, applyMiddleware( thunkMiddleware ) ); . .Copy the code

Now execute the following allChange() event to see if the page does not report an error and the name and age data have been changed.

2. Knowledge points

So let’s talk about applyMiddleware and thunkMiddleware

What is Middleware:

In Redux, middleware is a third-party extension between actions sent and actions delivered to the reducer, and middleware is a bridge between actions and stores.

See the explanation on applyMiddleware’s website.

Middleware lets you wrap a store’s dispatch() method to do what you want.

3, add

One final addition:

If you want to be able to print logs on the console every time you dispatch, hand-writing can be tedious.

Redux also provides such middleware to help us print logs.

Type YARN Add redux-Logger or NPM install –save redux-Logger to import the redux-Logger library.

Add the following code to SRC /index.js:

import { createLogger } from 'redux-logger'

const loggerMiddleware = createLogger()

const store = createStore(
  Reducer,
  applyMiddleware(
    thunkMiddleware,
    loggerMiddleware
  )
);
Copy the code

Well, go for it

Remember to double click