美文网首页
Context + Hook + HOC 实现React的状态管

Context + Hook + HOC 实现React的状态管

作者: 变态的小水瓶 | 来源:发表于2020-05-08 01:24 被阅读0次

    在使用React开发一个应用时,我们有时会遇到组件树中位置不同,层级不同的n多个组件需要状态共享的问题,我们可以使用redux/mobx来管理,当然context也为我们提供一个可行方案。

    先上一个实现效果:



    点击changeUser按钮后:


    image.png

    可以考虑分几个步骤来实现:

    第一,准备好要共享状态的组件:

    // app.jsx
    import React from 'react';
    import HomePage from "./page/HomePage";
    // 引入context的provider组件
    import { AppProvider } from "./store/appContext";
    
    function App() {
      return (
        <div className="App">
          App
          <AppProvider>
            <HomePage name={1} />
          </AppProvider>
        </div>
      );
    }
    
    export default App;
    

    第二,创建context,提供provider将需要共享状态的组件外层包裹,提供consumer高阶组件将需要消费状态的组件进行加工;

    // appContext.js
    import React, { createContext, useReducer } from 'react';
    const AppContext = createContext();
    
    function AppProvider(props) {
        const initialState = {
            user: "Amy Tong"
        };
        const reducer = (state, action) => {
            const { type, payload } = action;
            switch (type) {
                case "SET_USER":
                    return { ...state, user: payload }
                default:
                    break;
            }
        }
        const [state, dispatch] = useReducer(reducer, initialState)
        return (
            <AppContext.Provider value={{ state, dispatch }}>
                {props.children}
            </AppContext.Provider>
        )
    }
    
    const AppConsumer = Cmp => {
        return props => {
            return <AppContext.Consumer>
                {(ctx) => <Cmp {...props} {...ctx} />}
            </AppContext.Consumer>
        }
    }
    // 或如下的方法也可以
    const AppConsumer = Cmp => {
      return props => {
        const ctx = useContext(AppContext);
        return <Cmp {...props} {...ctx} />;
      };
    };
    
    export { AppProvider, AppConsumer, AppContext };
    

    第四,在HomePage组件中使用consumer,且通过props获取和修改状态值;

    // HomePage.js
    import React from 'react';
    // 引入appContext 提供的consumer高阶组件
    import { AppConsumer } from "../store/appContext";
    
    function HomePage(props) {
        const { state, dispatch } = props;
        const changeUser = () => {
            dispatch({ type: "SET_USER", payload: "Mike" })
        }
        return (
            <div>
                homepage
                {JSON.stringify(state)}
                <button onClick={changeUser}>changeUser</button>
            </div>
        )
    };
    
    export default AppConsumer(HomePage);
    

    关于react的context API 使用,见文档:https://react.docschina.org/docs/context.html

    相关文章

      网友评论

          本文标题:Context + Hook + HOC 实现React的状态管

          本文链接:https://www.haomeiwen.com/subject/rigtnhtx.html