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

2020-05-08  本文已影响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

上一篇下一篇

猜你喜欢

热点阅读