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);
  }
);
复制代码

 

posted @   行走的蒲公英  阅读(210)  评论(0编辑  收藏  举报
编辑推荐:
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
点击右上角即可分享
微信分享提示