在使用React开发一个应用时,我们有时会遇到组件树中位置不同,层级不同的n多个组件需要状态共享的问题,我们可以使用redux/mobx来管理,当然context也为我们提供一个可行方案。
先上一个实现效果:
点击changeUser按钮后:
可以考虑分几个步骤来实现:
第一,准备好要共享状态的组件:
// 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);复制代码