技术咨询、项目合作、广告投放、简历咨询、技术文档下载 点击这里 联系博主

# React useContext 和 useReducer 的使用

# 先了解一下 Context

Context 提供了一个无需为每层组件手动添加 props,就能在组件树间进行数据传递的方法。Context 设计目的是为了共享那些对于一个组件树而言是“全局”的数据。使用 context,我们可以避免通过中间元素传递 props;

常见的 API 有

  • React.createContext: 创建一个全局 context
  • Context.Provider: 在最顶层提供数据
  • Context.Consumer: 在子组件中消费数据
  • React.useContext: 使用 hooks 的方式消费数据

# 如何和 useReducer 结合

# 1. 编写 Reducer

import { createContext } from "react";

export interface IStateProps {
  is_verified?: boolean;
  is_adult?: boolean;
}
export type IActionProps = {
  type: "change_user_status";
  payload: Pick<IStateProps, "is_adult" | "is_verified">;
};

export const initState: IStateProps = {
  is_verified: false,
  is_adult: false,
};

export const userAuthStatusReducer = (
  state: IStateProps,
  action: IActionProps
): IStateProps => {
  switch (action.type) {
    case "change_user_status":
      return {
        ...state,
        ...action.payload, // 当然这里可以做一些其他的数据转换
      };
    default:
      throw new Error("reducer没有当前type方法");
  }
};

# 2. 编写 Context

export const UserAuthStatusContext = createContext<{
  state: IStateProps;
  dispatch: React.Dispatch<IActionProps>;
}>({
  state: initState,
  dispatch: () => {},
});

export const { Provider } = UserAuthStatusContext;
export const { Consumer } = UserAuthStatusContext;

# 3. 在根组件部分使用 Provider

注意: 这里不一定是根组件部分,但是一定需要在你使用 useContext 的父组件 使用 Provider

import React, { useReducer } from "react";
import Auth from "./components";
import { initState, Provider, userAuthStatusReducer } from "./reducer/status";

const App: React.FC = () => {
  const [state, dispatch] = useReducer(userAuthStatusReducer, initState);
  return (
    <Provider value={{ state, dispatch }}>
      <Auth />
    </Provider>
  );
};

export default App;

# 4. 使用 useContext 消费数据

注意点:跨 dom 是无法共享数据的,比如 动态创建了一个 dom,挂载到当前子 dom 树下是无法获取到 context 数据的,只能在同一个虚拟 DOM 树下才可以

import React, { useMemo, useContext, useState } from "react";
import "./index.scss";
import Confirm from "./components/Confirm";
import AuthDesc from "./components/AuthDesc";
import { UserAuthStatusContext } from "../reducer/status";

const prefix = "test-auth";

const Index: React.FC = () => {
  // 消费 state 的数据
  const { state, dispatch } = useContext(UserAuthStatusContext);

  return (
    <div className={`${prefix}`}>
      <div className={`${prefix}-container`}>
        <Confirm isAgree={isAgree !== ""} certificationStatus={state.status} />
        <AuthDesc />
        <div
          onClick={() => {
            dispatch({
              type: "change_user_status",
              payload: {
                is_verified: true,
                is_adult: true,
              },
            });
          }}
        >
          点击触发事件
        </div>
      </div>
    </div>
  );
};

export default Index;
【未经作者允许禁止转载】 Last Updated: 2/4/2024, 6:06:40 AM