Simple case explanation of using redux in react

Why do I want to use redux?

Some time ago, we started react. Recently, we found that there is an urgent need for communication between components in the process of using react, especially when axios requests back-end data asynchronously! for instance:

 
//Manufacturer's report arrival
class ReportArrivalGoods extends React.Component{
    constructor(props){
        super(props);
        this.state = {
columns:tableHead.ReportArrivalGoods / / this is the initialization header. It has a lot of contents. It will not be displayed
            data: []
          };
    }

    componentDidMount(){
     axios(
        {
            method: 'get',
            url: 'http://172.89.1.79/LogisticsSporadicBoardBackEnd/index.asmx/ReportArrivalGoods'
        })
        .then(
            res => {    
         this.setState(
                  data:NewState
            );
            }
        )
        .catch(
            error => {
                console.log(error);
            }
        );
    }

    render(){
        return(
            <Table
            style={{width: '100%'}}
            columns={this.state.columns}
            data={this.state.data}
            border={true}
            maxHeight={tableMaxHeight}
          />
        );
    }
    
}
 

We focus on the following componentDidMount() function

    componentDidMount(){
     axios(
        {
            method: 'get',
            url: 'http://172.89.1.79/LogisticsSporadicBoardBackEnd/index.asmx/ReportArrivalGoods'
        })
        .then(
            res => {    
         this.setState(
                  data:NewState
            );
            }
        )
        .catch(
            error => {
                console.log(error);
            }
        );
    }

This is a very familiar react life cycle hook function. I did one thing: after the page rendering, I asked the background for data and displayed it on the page. But those who have used axios know that they are asynchronous like ajax, that is to say, after you send a request, you will immediately execute the following code, and then() and catch() will be executed when the result of your request comes back. At the beginning, I simply and roughly wrote the whole function body into the hook directly. There is no problem in the implementation, but there are five components that need to use the hook function to request different data. If each component writes such a long string of code, on the one hand, it is not good-looking, on the other hand, there are too many duplicate codes. So I thought of encapsulating this function body, so I have the following code

 

//webservice Data request function
function AxiosGet(desinationURL){
    axios(
        {
            method: 'get',
            url: desinationURL
        })
        .then(
            res => {

                    );
            }
        )
        .catch(
            error => {
                console.log(error);
            }
        );
}

 

But if it is encapsulated, how can I set the state of my component? Tactfully, I came up with a way to create a modifyState() function with parameters inside the component. When making the AxiosGet() function, I passed the modifyState() function as a parameter to AxiosGet() and res.data as a parameter to modifyState() in AxiosGet() to achieve the purpose of setstate. It's a little convoluted, speaking in code

//webservice Data request function
function AxiosGet(desinationURL,ApplyNewState){
    axios(
        {
            method: 'get',
            url: desinationURL
        })
        .then(
            res => {
                ApplyNewState(res.data);
            }
        )
        .catch(
            error => {
                console.log(error);
            }
        );
}

The above is the data request function outside the component, and the following are the hook function inside the component and the function for passing in and getting data

  modifyState(NewState){
        this.setState(
            {
                data:NewState
            }
        );
    }
    componentDidMount(){
        AxiosGet('http://172.89.1.79/LogisticsSporadicBoardBackEnd/index.asmx/ReportArrivalGoods',
        this.modifyState
        );
    }

Well, it should have been understood by the discerning people. I cleverly completed the state update by transferring the function out of the component. Although the problem has been solved, it's really troublesome. If only I could update the state of the component outside the component. Someone has to say, the state is improving! Create a parent component for all components, update the status uniformly in the parent component and pass it to the child component in the form of props. Well, this is indeed a way, but the parent component does not express a special meaning, just like a div, without semantics, is there a better way? Baidu search react state, here comes, here he comes, the lamp light! redux comes on stage!

Redux uses seven steps

I don't want to explain the knowledge of redux here. That's what I know. The tutorials on the redux official website are very clear and can be learned directly. I mainly talk about the use of redux in react. As the title says, it only takes seven steps. As we all know, in redux, the three most important things are

{

action:,

Action processing function: reducer,

Status warehouse: store

}

Presumably, people who have gone through the official redux tutorial can easily sort out the relationship and specific operation, so the question is, how to bind the state and store of components to them in react? There are a lot of online posts, but as I said in the previous one, they are copied back and forth. They don't really talk about Xiaobai's ideas, and some of them are miscopied, which leads to readers' misunderstanding. Here, I make the most appropriate explanation from Xiaobai's perspective, and I believe that you can understand it after you listen to them. I'm a development environment built with create react app. I won't elaborate here. Don't say much, code! The directory structure is shown in the figure:

 

 

 

Step 1: install dependency:

npm i redux redux-react -s

Step 2: create action

// /actions/test.js

export const PLUS='PLUS';

export function plusActionCreator(){
    return{
        type:PLUS
    }
}

Step 3: create reducer

//  /reducers/test.js

import {PLUS} from '../actions/test'

const initState={count:0};

export function plusReducer(state=initState,action){
    switch(action.type){
        case PLUS:{
            return 
       { count:state.count+1;//The state returned here is only the state in the small range of plusReducer. It is important to understand this!!!
       }
    }
    default:return state;
  }
}
 

Step 4: create a store

// /index.js

const reducer=combineReducers({plus:plusReducer});//You need to transfer in json Object only. The object name represents the source reducer var store=createStore(reducer);

Above is the Redux part. You should be familiar with it. At this time, it is also the most important part: the combination of react and redux. It needs to be explained that the components of react can be divided into display components and container components. Display components are responsible for interface rendering, and container components are responsible for managing state for display components. All States of the presentation component are passed in through props.

Step 5: create a presentation component

// /index.js

function Test (props){
    return(
        <div>
            <p>Total count:{props.count}</p>
            <button onClick={props.plus}>add one-tenth</button>
        </div> 
    );
}

 

Step 6: generate container components through the connect method provided by react Redux

// /index.js

const CollectionComponent=connect(
    (state)=>{
        return{
            count:state.plus.count//It's important to note that the state yesadopt combinereducers Named in json Object names are delimited
                    //The json object count here corresponds to props.count in the display component
} }, (dispatch)=>{ return{ plus:bindActionCreators(plusActionCreator,dispatch)
       //The json object plus here also corresponds to the props.plus method in the presentation component
} } )(Test);//Test andDisplay component name is also corresponding

It's very important here. First of all, const CollectionComponent is the container component we need.

The connect (read,write) (destination) function has three parameters read,write and destination (Abstract name, for the convenience of understanding). The purpose of read is to return the state we want from the store. The purpose of write is to pass in action to update the state, and destination is used to bind to the specified display component.

Step 7: build a bridge between react and redux data interaction through the Provider component provided by react redux

// /index.js

ReactDOM.render(   
<Provider store={store}>//Here, the store created previously is passed to the Provider, so that the state in the store can be passed to the container component <CollectionComponent/>//As step 6 has bound the display component to the container component, you only need to write the container component here   </Provider>   ,document.getElementById('root'));

 

 

 

OVER! With this small demo, you can complete a simple accumulator. Finally, paste the complete source code, hey hey, yes!

// /reducers/test.js

import {PLUS} from '../actions/test'

const initState={count:0};

export function plusReducer(state=initState,action){
    switch(action.type){
        case PLUS:{
            return {
                count:state.count+1
            }
        }
        default:return state;
    }
}
// /actions/test.js

export const PLUS='PLUS';

export function plusActionCreator(){
    return{
        type:PLUS
    }
}
// /index.js

//react
import React from 'react'
import ReactDOM from 'react-dom'
//redux
import {connect,Provider} from 'react-redux'
import {bindActionCreators,combineReducers,createStore} from 'redux'
import {plusReducer} from './reducers/test'
import {plusActionCreator} from './actions/test'
//Presentation part
function Test (props){
    return(
        <div>
            <p>Here is count: {props.count}</p>
            <button onClick={props.plus}>add one-tenth</button>
        </div> 
    );
}
//redux Part
const reducer=combineReducers({plus:plusReducer});//You need to transfer in json Object only
var store=createStore(reducer);

const CollectionComponent=connect(
    (state)=>{
        return{
            count:state.plus.count//It's important to note that the state yes
                                  //adopt combinereducers Named in json Object names are delimited
        }
    },
    (dispatch)=>{
        return{
            plus:bindActionCreators(plusActionCreator,dispatch)
        }
    }
)(Test);

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

Finally, I'll give you a little Easter egg. The small demo of react router just made today is also nested in the above code.

//react
import React from 'react'
import ReactDOM from 'react-dom'
//redux
import {connect,Provider} from 'react-redux'
import {bindActionCreators,combineReducers,createStore} from 'redux'
import {plusReducer} from './reducers/test'
import {plusActionCreator} from './actions/test'
//router
import { BrowserRouter,Switch,Route,NavLink  } from 'react-router-dom';
//Presentation part
function Test (props){
    return(
        <div>
            <p>Here is count: {props.count}</p>
            <button onClick={props.plus}>add one-tenth</button>
        </div> 
    );
}
//redux Part
const reducer=combineReducers({plus:plusReducer});//You need to transfer in json Object only
var store=createStore(reducer);

const CollectionComponent=connect(
    (state)=>{
        return{
            count:state.plus.count//It's important to note that the state yes
                                  //adopt combinereducers Named in json Object names are delimited
        }
    },
    (dispatch)=>{
        return{
            plus:bindActionCreators(plusActionCreator,dispatch)
        }
    }
)(Test);

ReactDOM.render(
<Provider store={store}>
    <BrowserRouter >
        <Switch>
            <Route path="/class/classmates">
                <div>QianYingLi,HaoWu,ZhouHuiFan</div>
                <NavLink to="/class" activeClassName="fillInClassNameHere">
                    redirect to class
                </NavLink>
            </Route>
            <Route path="/class">
                <div>High one or two</div>
                <NavLink to="/class/classmates" activeClassName="hurray">
                    redirect to classmates
                </NavLink>
            </Route>
            <Route path="/">
                <CollectionComponent/>
            </Route>
        </Switch>
    </BrowserRouter >
</Provider>
,document.getElementById('root'));

Tags: Javascript React JSON axios npm

Posted on Sat, 02 Nov 2019 15:56:00 -0700 by kunalk