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 @ 2021-08-27 11:23  行走的蒲公英  阅读(207)  评论(0编辑  收藏  举报