useContext和useReducer配合管理公共数据
说明:现有一个小需求,切换全局社区id,页面全部数据都相应切换。选择其中一种实现方式就是使用useContext和useReducer配合管理这个公共数据id。
以下是大概步骤:
1. 新建GolobalID.tsx文件,贴代码:
import { createContext, useReducer } from "react";
export const UPDATE_ID = "UPDATE_ID";
/**
* 创建一个 GolobalID 组件
* GolobalID 组件包裹的所有组件都可以访问到全局的社区 id
*/
export const GolobalIDContext = createContext({
globalId: localStorage.getItem("globalId") || 0, // 从缓存获取社区id
dispatch: function ({}) {},
});
export const GolobalID = (props: any) => {
const reducer = (state: any, action: any) => {
switch (action.type) {
case UPDATE_ID:
return action.globalId;
default:
return state;
}
};
const [globalId, dispatch] = useReducer(
reducer,
localStorage.getItem("globalId") || 0
);
return (
<GolobalIDContext.Provider value={{ globalId, dispatch }}>
{props.children}
</GolobalIDContext.Provider>
);
};
2. 在入口组件App里写:
// 引入 import { GolobalID } from "app/hooks/GolobalID"; function App() { return ( <GolobalID> <BrowserRouter> <Switch> <Route path="/home" component={() => <Home menuList={menuList} />} /> {menuList.map((item) => { return ( <Route key={item.title} path={item.path} component={item.component} /> ); })} <Redirect to="/home" /> </Switch> </BrowserRouter> </GolobalID> ); } export default App;
3.在获取id或者是切换id的组件页面:
import { GolobalIDContext, UPDATE_ID } from "app/hooks/GolobalID";
const { dispatch } = useContext(GolobalIDContext);
useEffect(() => {
// 获取社区列表
Api.getMainCity().then((res) => {
setCity(res.data[0].name);
if (res.data) {
localStorage.setItem("globalId", res.data[0].id);
// 获取默认的社区id
dispatch({ type: UPDATE_ID, globalId: res.data[0].id });
}
setList(res.data);
});
}, []);
// 切换id的方法:更新id
const handleChange = (value: any) => {
list.forEach((v: any) => {
if (v.name === value) {
localStorage.setItem("globalId", v.id);
// 切换全局社区id
dispatch({ type: UPDATE_ID, globalId: v.id });
}
});
};
4.在其他需要切换请求的组件页面:
import { GolobalIDContext } from "app/hooks/GolobalID";
const { globalId } = useContext(GolobalIDContext);
useEffect(() => {
// 获取男女数量 计算百分比
Api.getSexCount().then((res) => {
let boyBit = (res.data["男"] / (res.data["男"] + res.data["女"])) * 100;
let girlBit = (res.data["女"] / (res.data["男"] + res.data["女"])) * 100;
let data = {
boyBit: boyBit,
girlBit: girlBit,
boyNum: res.data["男"],
girlNum: res.data["女"],
};
setSexItem(data);
});
}, [globalId]);
// 监听到globalid变化的时候,重新执行请求
5. 全局id是每个请求都携带的,request.ts里面:
request.interceptors.request.use( (config) => { // 全局请求携带id const id = Number(localStorage.getItem("globalId")) || 0; config.params = { areaId: id }; // config.data = { areaId: id }; return config; }, (error) => { console.log(error); return Promise.reject(error); } );

浙公网安备 33010602011771号