【React hooks】useReducer

36 阅读1分钟

使用场景

  • 如果state是一个数组或者对象
  • 如果state变化很复杂,经常一个操作需要修改很多state
  • 如果需要在深层子组件里面去修改一些状态

参数

  1. reducer函数
  2. 初始化的state
import { useReducer, useState } from "react";

export default function App() {
  let inititalState = { count: 0 };
  const reducer = (state, action) => {
    switch (action.type) {
      case "add":
        return { count: state.count + 1 };
      case "desc":
        return { count: state.count - 1 };
      case "reset":
        return inititalState;
      default:
        throw new Error();
    }
  };
  const [state, dispatch] = useReducer(reducer, inititalState);
  return (
    <div>
      <p>{state.count}</p>
      <button onClick={() => dispatch({ type: "add" })}>add</button>
      <button onClick={() => dispatch({ type: "desc" })}>desc</button>
      <button onClick={() => dispatch({ type: "reset" })}>reset</button>
    </div>
  );
}

搭配useContext实现跨组件状态管理

实现:父组件定义状态数据,孙组件更改状态

// Outer
import { useReducer } from "react";
import { Provider } from "./context";
import Inner from "./inner";

export default function Outer() {
  let inititalState = { count: 0 };
  const reducer = (state, action) => {
    switch (action.type) {
      case "add":
        return { count: state.count + 1 };
      case "desc":
        return { count: state.count - 1 };
      case "reset":
        return inititalState;
      default:
        throw new Error();
    }
  };
  const [state, dispatch] = useReducer(reducer, inititalState);
  return (
    <Provider value={{ state, dispatch }}>
      <p>{state.count}</p>
      <Inner />
    </Provider>
  );
}
//Inner
import Son from "./Son";

export default function Inner() {
  return (
    <div>
      <Son />
    </div>
  );
}
//Son
import React, { useContext } from "react";
import { TestContext } from "./context";

export default function Son() {
  const { dispatch } = useContext(TestContext);
  return (
    <div>
      <button onClick={() => dispatch({ type: "add" })}>add</button>
      <button onClick={() => dispatch({ type: "desc" })}>desc</button>
      <button onClick={() => dispatch({ type: "reset" })}>reset</button>
    </div>
  );
}

总结

  • 页面state很简单,可以直接使用useState
  • 页面state比较复杂(state是一个对象或者state非常多散落在各处)请使用userReducer
  • 页面组件层级比较深,并且需要子组件触发state的变化,可以考虑useReducer + useContext