使用 useContext && useReducer 代替 Redux 进行状态管理

react-redux 思想

  1. 创建 actions 纯函数来描述行为和所需数据
  2. 创建 reducers 去处理一类 actions 的不同类型的 action
  3. 创建 store 去合并多个不同的 reducers
  4. 在 react 主入口文件通过 Provider 去注入 store
  5. 某个组件需要 store 的中的某个状态,通过 connect HOC 去将 state 和 dispatch 关联到该组件的 props

需要用到的API

  • createContext:创建一个 Context 对象,提供需要层层传递的数据
  • Context.Provider:将数据从外层的高阶组件注入
  • useContext:接收一个 context 对象,接收的 context 对象来源于距当前组件最近的 Context.Provider 组件。当注入的值改变时,该 hook 会重新触发渲染
  • useReducer:类似 useState,但是接收的是 reducer 和初始状态,返回的是当前的 state 和 dispatch 方法。需要特别说明的是,react官方文档指出,react对dispatch进行了特别的处理,可以不需要使用 useCallback 进行优化。

使用 useContext && useReducer 代替的思路

  1. 使用 createContext 创建 context,其中初始化了 state的类型 和 actions的种类
export const initState = {
  color: "blue"
};

export const ColorContext = createContext({
  state: initState,
  actions: {
    updateColor: (color: string): void => {}
  }
});
  1. 创建 reducer 去处理不同类型的 action
export enum ColorActionTypes {
  UPDATE_COLOR = "UPDATE_COLOR"
}

export const reducer = (state, action) => {
  switch (action.type) {
    case ColorActionTypes.UPDATE_COLOR:
      return {
        ...state,
        color: action.color
      };
    default:
      return state;
  }
};
  1. 构建一个高阶的Provider组件,使用 useReducer 去构建初始状态并获取到 dispatch 函数,使用 dispatch 函数去发送不同的 action 到 reducer 对状态进行自动处理
import { FC, useReducer } from "react";

import { ColorContext, reducer, initState, ColorActionTypes } from "./utils";

const ColorProvider: FC = ({ children }) => {
  const [state, dispatch] = useReducer(reducer, initState);
  const updateColor = (color: string) =>
    dispatch({
      type: ColorActionTypes.UPDATE_COLOR,
      color
    });
  const actions = {
    updateColor
  };
  return (
    
      {children}
    
  );
};

export default ColorProvider;
  1. 自定义一个hook,里面使用 useContext 获取到 state 和 actions,根据场景抛出某些 state 和 某些 actions
export const useColorContext = () => {
  const { state, actions } = useContext(ColorContext);
  const updateColor = (color) => actions.updateColor(color);
  return {
    color: state.color,
    updateColor
  };
};
  1. 在项目主入口文件使用高阶的Provider组件进行包裹,另外在需要使用 state 和 actions 的地方调用自定义的 hook 即可
export default function App() {
  return (
    
); }

Button 组件导入 useColorContext 使用 updateColor action去更新状态

import React from "react";

import { useColorContext } from "./utils";

const Button = (props) => {
  const { updateColor } = useColorContext();
  return (
    
); }; export default Button;

Text 组件导入 useColorContext, 使用 color 状态

import React from "react";
import { useColorContext } from "./utils";

const Text = (props) => {
  const { color } = useColorContext();
  return 
字体颜色为:{color}
; }; export default Text;

代码Demo地址:codesandbox:useContext&&useReducer
代码仓库地址:github: hooks-redux

你可能感兴趣的:(使用 useContext && useReducer 代替 Redux 进行状态管理)