Re learning react — context / reducer

Time:2020-9-28

1. Context concept

Context is also the context, which is convenient for sub level components to share data. Just look at chestnuts

//Create a context
const context = React.createContext({count:0,add:function(){}});

//Data provided by
const Provider = context.Provider;
//Consumer: using data
const Consumer = context.Consumer;

const Child = (props: any) => {
    return <div>
        <span>{props.count}</span>
        <button onClick={props.add}>add</button>
    </div>;
};

const IndexView = () => {
    const [count, setCount] = useState(0);
    const add = () => {
        setCount(count + 1);
    };
    //Use provider and consumer (can be more than one) to transfer data
    return <Provider value={{count, add}}>
        <Consumer>
            {
                <! -- by function -- >
                value => <Child {...value}/>
            }
        </Consumer>
    </Provider>;
};

We can see that although child can obtain data, it is not convenient to use. If it is a multi-level sub component, it is not easy to use

2、 Usereducer

The use reducer method is provided in react hook above 16.8 to solve this problem,
The usage is as follows

  • Store file
export const state = {
    name: 'lihaixing',
    age: 32,
    sons: []
};

export function Reducer(state, action) {
    if (!action.type && !action.data) {
        return {
            ...state,
            ...action
        };
    }
    switch (action.type) {
        case 'update':
            return {
                ...state,
                ...action.data
            };
        default:
            return state;
    }
}
//Context
export const context = React.createContext({
    state, dispatch: (obj: any) => {}
});
  • Container component
import React, { useReducer } from 'react';
import { state as initState, Reducer,context } from './store';

import Com1 from './comp1'
import Com2 from './comp2'

const IndexView = () => {
    const [state, dispatch] = useReducer(Reducer, initState);

    return <context.Provider value={{ state, dispatch }}>
        <Com1 />
        <Com2 />
    </context.Provider>
};

export default IndexView;
  • Comp1 component
import React, { useContext } from 'react';
import { context } from './index';

const IndexView = () => {
    const {state, dispatch} = useContext(context);
    const {name, age, sons} = state;
    const setAge = () => {
        dispatch({age: age + 1});
    };
    const setSons = () => {
        dispatch({sons: [...sons, 1]});
    };
    return <div>
        {name} <br/>
        {age} <br/>
        {sons} <br/>
        < button onclick = {setage} > button age < / button >
        < button onclick = {setsons} > buttons sons < / button >
    </div>;
};

export default IndexView;
  • Comp2 component
import React, { useContext } from 'react';
import { context } from './index';

const IndexView = () => {
    const {state} = useContext(context);
    const {name, age, sons} = state;
    return <div>
        {name} <br/>
        {age} <br/>
        {sons} <br/>
    </div>;
};

export default IndexView;

Summary:
1、Usereducer makes the data maintainable and responsive and returns the dispatch method
2、The usecontext makes it unnecessary for us to pass parameters through the consumer. No matter how many sub components there are, as long as the context is introduced, we can get the responsive state data and the dispatch method that triggers the data change by using the usecontext method