useReducer了解及使用

138 阅读2分钟

官网

useReducer(reducer, initialArg, init?)

useReducer 是为了给组件内部添加reducer。

const [state, dispatch] = useReducer(reducer, initialArg, init?)

在组件的顶层调用useReducer,用一个reducer来管理它的状态。

// 用法
import { useReducer } from 'react';

function reducer(state, action) {
  // ...
}

function MyComponent() {
  const [state, dispatch] = useReducer(reducer, { age: 42 });
  // ...

参数:

reducer:指定如何更新状态的reducer函数。它必须是纯的,应该将状态和动作作为参数,并且应该返回下一个状态。状态和动作可以是任何类型。

initialArg:计算初始状态的值。它可以是任何类型的值。如何从它计算初始状态取决于下一个init参数。

可选的init:应该返回初始状态的初始化函数。如果未指定,则初始状态设置为initialArg。否则,初始状态被设置为调用init(initialArg)的结果。

返回值:

useReducer返回一个包含两个值的数组:

  1. 当前状态。在第一次渲染期间,它被设置为init(initialArg)或initialArg(如果没有init)。
  2. 调度函数,允许您将状态更新为不同的值并触发重新呈现。

注意:在严格模式下,开发环境React会两次调用你的reducer和初始化器,以帮助你找到意外的杂质。

reducer :修改状态的管理方法

dispatch:派发任务,通知reducer执行

action:派发的行为对象
派发的行为标识,必须具备type属性 在reducer内可以基于不同的行为标识,修改不同的状态的状态信息

state:容器中的状态

例子:使用useReducer更新状态值

import React, { useReducer } from "react";
import { Button } from "antd";

const initialState = {
    num: 0
};
const reducer = function reducer(state, action) {
    state = { ...state };
    switch (action.type) {
        case 'plus':
            state.num++;
            break;
        case 'minus':
            state.num--;
            break;
        default:
    }
    return state;
};

const Demo = function Demo() {
    let [state, dispatch] = useReducer(reducer, initialState);

    return <div className="box">
        <span>{state.num}</span>
        <br />
        <Button type="primary" onClick={() => {
            dispatch({ type: 'plus' });
        }}>增加</Button>&nbsp;
        <Button type="primary" onClick={() => {
            dispatch({ type: 'minus' });
        }}>减少</Button>
    </div>;
};
export default Demo;

运行结果:

图片.png

整体来看,这个 reducer 写法和 redux 的写法十分类似

但是redux是创建了全局store,整体派发 useReducer 内使用了局部store【reducer】,在组件内使用;在使用上等价于createStore

useReducer是对useState的升级处理

  • 普通需求处理的时候,基本都是useState直接处理,不会使用useReducer
  • 但是如果一个组件的逻辑很复杂,需要大量的状态/大量修改状态的逻辑,此时使用useReducer管理这些状态会更好一些
    • 不需要再基于useState一个个的去创建状态了
    • 所有状态修改的逻辑,全部统一化处理了!!