To solve the pain points

When the hierarchy of components is very deep and the components need to use the same data, it is too cumbersome to pass props to the parent component through the promotion of the component.

Application Requirement Scenarios

1. Sibling components share state (that is, the same data). UseContext is suitable

2. UseContext is suitable for sharing state between parent and grandson components (especially if the component tree is deep)

3. The parent and child components share state. You are advised to use useState+props to transfer parameters between common parent and child components.

4. State is shared globally among all components of the project: it is recommended to use the UmiJS plug-in @umijs/plugin-initial-state and @umijs/plugin-model together to achieve this.

Context can be used when different levels in the component tree need to access the same data source to communicate between components or subscribe to the specified context object.

features

A subscription approach to context variables is suitable for passing variables directly across the component hierarchy, State sharing < myContext. Provider value={{setStep, setCount, setNumber, FetchData}} /> fetchData {dispatch} ={{dispatch}; It is better to use useState+props to transfer parameters between parent and child components of only one layer.

Usage examples

Example 1: The definition of useContext+useState shares data

Parentcomponent. TSX: import React, {useContext} from “React “; import ReactDOM from “react-dom”;

const TestContext= React.createContext({}); Function App() {return (< testContext. Provider value={{username: ‘hot water ‘,}} >}

Subcomponent 1: sub1Component.tsx:

const sub1Component= () => { const { username } = useContext(TestContext)

return (

{username}

return (

1 message for {username}

Import React, {useReducer} from ‘React ‘; import Child from ‘./Child’; import { MyContext } from ‘./context-manager’;

const initState = { count: 0, step: 0, number: 0 };

const reducer = (state, action) => { switch (action.type) { case ‘stepInc’: return Object.assign({}, state, { step: state.step + 1 }); case ‘numberInc’: return Object.assign({}, state, { number: state.number + 1 }); case ‘count’: return Object.assign({}, state, { count: state.step + state.number }); default: return state; }}

export default (props = {}) => { const [state, dispatch] = useReducer(reducer, initState); const { step, number, count } = state;

return (
    <MyContext.Provider value={{ dispatch }}>
        <Child step={step} number={number} count={count} />
    </MyContext.Provider>
);
Copy the code

} subcomponent: import React, {useContext, memo} from ‘React ‘;

import { MyContext } from ‘./context-manager’;

export default memo((props = {}) => { const { dispatch } = useContext(MyContext);

return (
    <div>
        <p>step is : {props.step}</p>
        <p>number is : {props.number}</p>
        <p>count is : {props.count}</p>
        <hr />
        <div>
            <button onClick={() => { dispatch({ type: 'stepInc' }) }}>step ++</button>
            <button onClick={() => { dispatch({ type: 'numberInc' }) }}>number ++</button>
            <button onClick={() => { dispatch({ type: 'count' }) }}>number + step</button>
        </div>
    </div>
);
Copy the code

}); Example 3: Pass parameters to the parent function component using normal props without useContext:

Parent (function component) : import Child from ‘Child’; // Introduce child components

const Father =() => {

Const func= () => {console.log(" parent ")} return <Child func=func> const func= () => {console.log(" parent ")} return <Child func=func>Copy the code

}

Const Child = (props)=> {const Child = (props)=> {

const handleClick = () => { const {func}=props; func(); } return <button onclick={this.handleClick}> subcomponent </button>Copy the code

}