useReducer 与 useState 对比 选择 useReducer() 而非 useState() 的 3 个理由

2025-06-10

useReducer 与 useState 对比选择 useReducer() 而非 useState() 的 3 个理由

它是什么

useReducer()是 React Hooks API 中的一个方法,与 类似,useState但能让你更好地控制状态。它接受一个 reducer 函数和初始状态作为参数,并返回状态和 dispatch 方法:

const [state, dispatch] = React.useReducer(reducerFn, initialState, initFn);
Enter fullscreen mode Exit fullscreen mode

Reducer(之所以这样称呼,是因为你会将函数类型传递给数组方法Array.prototype.reduce(reducer, initialValue))是源自 Redux 的一种模式。如果你不熟悉 Redux,简而言之,Reducer 是一个纯函数,它接受先前的状态和动作作为参数,并返回下一个状态。

(prevState, action) => newState
Enter fullscreen mode Exit fullscreen mode

Actions 是描述发生了什么的信息,Reducer 根据这些信息指定状态应该如何变化。Actions 通过dispatch(action)方法传递。

使用它的 3 个理由

大多数情况下,使用useState()基于 的方法就能很好地解决问题useReducer()。但在某些情况下,useReducer()这种方法更可取。

下一个状态取决于前一个状态

当状态依赖于前一个状态时,使用此方法总是更好的。它将为您提供更可预测的状态转换。简单的例子如下:

function reducer(state, action) {
  switch (action.type) {
    case 'ADD': return { count: state.count + 1 };
    case 'SUB': return { count: state.count - 1 };
    default: return state;
  }
}

function Counter() {
  const [state, dispatch] = React.useReducer(reducer, { count: 0 });
  return (
    <>
      Count: {state.count}
      <button onClick={() => dispatch({type: 'ADD'})}>Add</button>
      <button onClick={() => dispatch({type: 'SUB'})}>Substract</button>
    </>
  );
}
Enter fullscreen mode Exit fullscreen mode

复杂状态形状

当状态包含多个原始值时,例如嵌套对象或数组。例如:

const [state, dispatch] = React.useReducer(
  fetchUsersReducer,
  {
    users: [
      { name: 'John', subscribred: false },
      { name: 'Jane', subscribred: true },
    ],
    loading: false,
    error: false,
  },
);
Enter fullscreen mode Exit fullscreen mode

管理这个本地状态更容易,因为参数相互依赖,并且所有逻辑都可以封装到一个 reducer 中。

易于测试

Reducer 是纯函数,这意味着它们没有副作用,并且对于相同的参数必须返回相同的结果。由于它们不依赖于 React,因此测试起来更容易。让我们从计数器示例中取出一个 Reducer,并使用模拟状态进行测试:

test("increments the count by one", () => {
  const newState = reducer({ count: 0 }, { type: "ADD" });
  expect(newState.count).toBe(1)
})
Enter fullscreen mode Exit fullscreen mode

结论

useReducer()是一种替代方案useState(),它能让您更好地控制状态管理,并简化测试。所有情况都可以用useState()此方法完成,因此总而言之,请使用您熟悉的方法,并且它对您和同事来说更容易理解。

鏂囩珷鏉ユ簮锛�https://dev.to/spukas/3-reasons-to-usereducer-over-usestate-43ad
PREV
useEffect() 的 4 种方法
NEXT
如何使用 JavaScript 检查用户位置 基于位置的响应 地理定位 警告