useState 和 useReducer 的区别及应用场景

useState 和 useReducer 都是 React 中常用的 Hook,用于管理组件的状态。它们虽然都可以用来管理状态,但在使用时有一些区别。

useState 适用于简单的状态管理,能够方便地定义和修改组件的状态。通常可以使用数组结构

例如:

js 复制代码
import React, { useState } from 'react';

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

  function handleIncrement() {
    setCount(count + 1);
  }

  function handleDecrement() {
    setCount(count - 1);
  }

  return (
    <div>
      <h1>{count}</h1>
      <button onClick={handleIncrement}>+</button>
      <button onClick={handleDecrement}>-</button>
    </div>
  );
}

useReducer 则适用于更复杂的状态管理,例如状态变化需要根据多种信息进行计算或需要进行异步操作等情况。useReducer 可以传入一个 reducer 函数和一个初始状态,根据 dispatch 派发的 action 对状态进行更新,例如:

js 复制代码
import React, { useReducer } from 'react';

function reducer(state, action) {
  switch (action.type) {
    case 'increment':
      return { ...state, count: state.count + 1 };
    case 'decrement':
      return { ...state, count: state.count - 1 };
    default:
      throw new Error();
  }
}

function Counter() {
  const [state, dispatch] = useReducer(reducer, { count: 0 });

  function handleIncrement() {
    dispatch({ type: 'increment' });
  }

  function handleDecrement() {
    dispatch({ type: 'decrement' });
  }

  return (
    <div>
      <h1>{state.count}</h1>
      <button onClick={handleIncrement}>+</button>
      <button onClick={handleDecrement}>-</button>
    </div>
  );
}

以下是比较它们的几种方法:

  • 代码体积: 通常,在使用 useState 时,一开始只需要编写少量代码。而 useReducer 必须提前编写 reducer 函数和需要调度的 actions。但是,当多个事件处理程序以相似的方式修改 state 时,useReducer 可以减少代码量。

  • 可读性: 当状态更新逻辑足够简单时,useState 的可读性还行。但是,一旦逻辑变得复杂起来,它们会使组件变得臃肿且难以阅读。在这种情况下,useReducer 允许你将状态更新逻辑与事件处理程序分离开来。

  • 可调试性: 当使用 useState 出现问题时, 你很难发现具体原因以及为什么。 而使用 useReducer 时, 你可以在 reducer 函数中通过打印日志的方式来观察每个状态的更新,以及为什么要更新(来自哪个 action)。 如果所有 action 都没问题,你就知道问题出在了 reducer 本身的逻辑中。 然而,与使用 useState 相比,你必须单步执行更多的代码。

  • 可测试性: reducer 是一个不依赖于组件的纯函数。这就意味着你可以单独对它进行测试。一般来说,我们最好是在真实环境中测试组件,但对于复杂的状态更新逻辑,针对特定的初始状态和 action,断言 reducer 返回的特定状态会很有帮助。

  • 个人偏好: 并不是所有人都喜欢用 reducer,没关系,这是个人偏好问题。你可以随时在 useStateuseReducer 之间切换,它们能做的事情是一样的!

如果你在修改某些组件状态时经常出现问题或者想给组件添加更多逻辑时,我们建议你还是使用 reducer。当然,你也不必整个项目都用 reducer,这是可以自由搭配的。你甚至可以在一个组件中同时使用 useStateuseReducer

迁移状态逻辑至 Reducer 中 -- React 中文文档 (docschina.org)

相关推荐
香蕉可乐荷包蛋2 分钟前
浅入ES5、ES6(ES2015)、ES2023(ES14)版本对比,及使用建议---ES6就够用(个人觉得)
前端·javascript·es6
未来之窗软件服务36 分钟前
资源管理器必要性———仙盟创梦IDE
前端·javascript·ide·仙盟创梦ide
liuyang___2 小时前
第一次经历项目上线
前端·typescript
西哥写代码2 小时前
基于cornerstone3D的dicom影像浏览器 第十八章 自定义序列自动播放条
前端·javascript·vue
清风细雨_林木木2 小时前
Vue 中生成源码映射文件,配置 map
前端·javascript·vue.js
FungLeo2 小时前
node 后端和浏览器前端,有关 RSA 非对称加密的完整实践, 前后端匹配的代码演示
前端·非对称加密·rsa 加密·node 后端
雪芽蓝域zzs3 小时前
JavaScript splice() 方法
开发语言·javascript·ecmascript
不灭锦鲤3 小时前
xss-labs靶场第11-14关基础详解
前端·xss
不是吧这都有重名3 小时前
利用systemd启动部署在服务器上的web应用
运维·服务器·前端
霸王蟹3 小时前
React中巧妙使用异步组件Suspense优化页面性能。
前端·笔记·学习·react.js·前端框架