`useReducer` 全解析:从 React 小白到面大厂,你只差这把状态管理的刀

105 阅读6分钟

别让状态把你折磨得像状态一样复杂。


前言

如果你是这样的小白:

  • useState 用得飞起,但状态一多就开始写 props 传到怀疑人生;
  • 老板跟你说:“咱要不要上个 Redux?” 你一脸问号:useContext 不行吗?useReducer 又是啥?

别慌,这篇文章就是你的“救命顺风车”:

  • 带你用最简单的示例,搞懂 useReduceruseState 有啥区别;
  • 让你知道为什么它被称作 “简易 Redux”;
  • 最后还能抄一份“可跑 Demo”到自己项目里,管理多状态爽到飞起!

🐣 useState 能干嘛?为啥还要 useReducer

useState 很好用,小而美:

const [count, setCount] = useState(0);

简单场景:按钮点一下 +1,完美。


可一旦你状态一多,比如:

  • isLogin:登录态
  • theme:暗黑/明亮模式
  • todos:代办事项列表
  • count:页面点击次数
  • age:用户年龄

你就得写一堆 useState,传来传去,props drilling(钻头传递)转到手抖。

这时,useReducer 出场了。


useReduceruseState 的加强版

官方解释:

useReduceruseState 的替代方案,用于更复杂的状态逻辑。

一句话:
多状态、相互依赖、需要统一修改,就该用 useReducer


一个最简单的例子:从 useStateuseReducer

看懂下面这个例子,你就赢了:

const [state, dispatch] = useReducer(reducer, initialState);

拆开说:

名字意义
state当前状态(可以是对象)
dispatch派发“状态修改命令”
reducer纯函数,告诉状态怎么改
initialState初始值

对比 useState

const [count, setCount] = useState(0);

你只能一个状态一个钩子。
useReducer 可以这样:

const initialState = {
  count: 0,
  age: 21
};

然后所有状态都放 state 里,改就用 dispatch
高级得像小型 Redux。


reducer:状态管理的灵魂

reducer 这个词很玄乎,其实就是个纯函数,干一件事: (纯函数是什么我这里便不再详细介绍哦,如果有需要可以看看其他文章或者问问ai)

相同输入,一定相同输出,且不搞副作用!

官方约束:

  • 不能发请求
  • 不能改 DOM
  • 不能偷偷改外部变量

只负责把:

新状态 = reducer(旧状态, action)

像个生产线工厂,扔什么料(action),产什么货(state)。


实战示例:多状态管理 + 派发命令

下面,咱们直接上代码,我来帮你理理思路


import {
  useState,
  useReducer
} from 'react';
import './App.css';

// ---------------------------
//  定义初始状态
const initialState = {
  count: 0,
  age: 21
};

// ---------------------------
//  定义 reducer:纯函数,状态工厂
const reducer = (state, action) => {
  switch (action.type) {
    case 'increment':
      return {
        count: state.count + 1,
        age: state.age + 1
      };
    case 'decrement':
      return {
        count: state.count - 1,
        age: state.age - 1
      };
    case 'incrementByNum':
      return {
        ...state,
        count: state.count + Number(action.payload)
      };
    default:
      return state;
  }
};

// ---------------------------
//  App 组件
function App() {
  const [input, setInput] = useState(0); // 控制 input 输入

  // useReducer:旧状态 + dispatch 派发
  const [state, dispatch] = useReducer(reducer, initialState);

  return (
    <>
      <h2>Count: {state.count}</h2>
      <h2>wcy的Age: {state.age}</h2>

      <button onClick={() => dispatch({ type: 'increment' })}>+1</button>
      <button onClick={() => dispatch({ type: 'decrement' })}>-1</button>

      <br /><br />

      <input
        type="number"
        value={input}
        onChange={e => setInput(e.target.value)}
      />
      <button onClick={() => dispatch({ type: 'incrementByNum', payload: input })}>
        加上输入的数字
      </button>
    </>
  );
}

export default App;

🧩 核心点拆解

初始状态 initialState
initialState 就是一份“状态清单”,它把你要用的所有状态集中放在一个对象里,比如页面上的数字、用户年龄、是否登录、主题颜色……都能放进去。
这样做的好处是:状态都在一块,方便管理、方便看,也方便后期扩容。以后要新增状态,直接在 initialState 里加字段就行,整个状态树一目了然。


reducer
reducer 是整个状态管理的大脑,它是一个纯函数,唯一职责是:
根据输入(旧状态 + action),计算并返回新的状态。
它不会做多余的事,比如网络请求、改外部变量、改页面元素,这叫“没有副作用”,这样状态就特别可靠可预测,不容易出 bug。
想改状态,只能通过 reducer 里定义好的“规则”来改,这就是它可控、可维护的核心原因。


dispatch
dispatch 可以理解成“指挥棒”,谁要改状态都得先通过它发出“命令”,这个命令就是 action(带 type 和可选的参数 payload)。
dispatch 自己不会直接改状态,它只负责把这条指令交给 reducer,由 reducer 按规则生产新的状态,然后交给 React 去重新渲染。
所以:谁改状态,流程清晰;要改啥,全程可追溯


多状态同时管理
在实际开发里,一个页面往往不是只有一个状态,比如点个按钮会改多个值,像“点赞数 +1 的同时,用户积分 +10”。
reducer 管理时,这些状态都在一个地方,彼此依赖也没关系,只要在同一个 case 里写清楚就好,所有状态变动都由同一个大脑统筹,多状态之间的逻辑关系就能清清楚楚,不会乱套


界面由状态驱动
最妙的一点是:只要状态变了,React 会自动重新渲染相关的地方。
也就是说,你只管专心用 dispatch 改状态,别动别的,界面更新这件事 React 会帮你兜底,不会有“状态改了但是页面没变”的情况。
整个思路就是“数据驱动视图”,状态是源头,界面只是结果,维护起来特别省心。


🌟 这 5 个点串起来,就是 useReducer 的核心哲学:

所有状态集中管理 → 用纯函数可靠计算 → 用 dispatch 统一触发 → 多状态一起管理 → 视图自动响应


懂了这套思路,你就能把 useReducer 玩得比 useState 更灵活,还能平滑过渡到更大规模的状态管理(比如配合 useContext、再到 Redux),从此告别混乱状态,面试吹起来也底气十足!


useReducerRedux 有啥关系?

useReducer = 迷你版 Redux

  • reducer 概念一样:纯函数,状态工厂

  • dispatch 概念一样:统一派发命令

  • 只是 useReducer 没有:

    • 全局中间件(比如 thunk
    • 时间旅行(Redux DevTools)
    • 分模块拆分 reducer(可组合)
    • 跨组件 context(需要 useContext 一起用)

所以,很多面试官会问:

“有了 useReducer + useContext,为啥还要 Redux?”

✅ 小型项目就够了,省事。
✅ 大型项目状态复杂、有异步流、需要多人协作调试?上 Redux 更香。


小结一句话

useReducer 本质就是帮你写了个小型状态机,
所有的状态都按纯函数来生产,
这样你的状态可预测、可回放、可维护。


🎉 面大厂的思维点

如果有面试官考你:

“为什么要纯函数?”

你可以斩钉截铁:

“相同输入,输出可预测。没有副作用,状态可调试、可追溯,这就是状态管理的根本价值。”

然后举个例子:

“Redux 的 reducer 就是纯函数。useReducer 也一样。状态生产器嘛!”

这时候,面试官嘴角上扬,你已经赢了一半。


写在最后

useReducer 是你从 useState 升级到 Redux 的必经之路。

记住这条成长线:

useState → useReducer → useReducer + useContext → Redux → Redux + 中间件

一步步来,你就会从状态小白,成长为状态大师。


如果你觉得有用,点个赞 ❤️ + 收藏 🏷️,让更多刚学 React 的同学少踩坑,也欢迎评论区分享你的“状态管理血泪史”!


作者:wcy的状态工厂

用最简单的语言,写最靠谱的代码。