从简单到复杂:何时用 useState,何时用 useReducer?

在 React 开发中,状态管理是驱动组件交互和数据流的核心。随着项目复杂度的提升,开发者常常面临一个看似简单却至关重要的抉择:我该使用 useState,还是 useReducer

同样是一个 注册表单 (字段:usernameemailpasswordconfirmPasswordacceptTerms),用 useStateuseReducer 各写一遍,方便直观对比。

useState 版本

jsx 复制代码
import { useState } from 'react';

function RegisterFormUseState() {
  const [username, setUsername] = useState('');
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const [confirmPassword, setConfirmPassword] = useState('');
  const [acceptTerms, setAcceptTerms] = useState(false);

  const handleSubmit = (e) => {
    e.preventDefault();
    if (password !== confirmPassword) {
      alert('两次密码不一致!');
      return;
    }
    console.log({ username, email, password, acceptTerms });
    resetForm();
  };

  const resetForm = () => {
    setUsername('');
    setEmail('');
    setPassword('');
    setConfirmPassword('');
    setAcceptTerms(false);
  };

  return (
    <form onSubmit={handleSubmit}>
      <input value={username} onChange={(e) => setUsername(e.target.value)} placeholder="用户名" />
      <input value={email} onChange={(e) => setEmail(e.target.value)} placeholder="邮箱" />
      <input type="password" value={password} onChange={(e) => setPassword(e.target.value)} placeholder="密码" />
      <input type="password" value={confirmPassword} onChange={(e) => setConfirmPassword(e.target.value)} placeholder="确认密码" />
      <label>
        <input type="checkbox" checked={acceptTerms} onChange={(e) => setAcceptTerms(e.target.checked)} />
        同意条款
      </label>
      <button type="submit">注册</button>
      <button type="button" onClick={resetForm}>重置</button>
    </form>
  );
}

特点

  • 每个字段一个 useState
  • 重置表单需要逐个清空。
  • 字段多了会有很多重复 setter。

useReducer 版本

jsx 复制代码
import { useReducer } from 'react';

const initialState = {
  username: '',
  email: '',
  password: '',
  confirmPassword: '',
  acceptTerms: false,
};

function reducer(state, action) {
  switch (action.type) {
    case 'updateField':
      return { ...state, [action.field]: action.value };
    case 'reset':
      return initialState;
    default:
      return state;
  }
}

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

  const handleSubmit = (e) => {
    e.preventDefault();
    if (state.password !== state.confirmPassword) {
      alert('两次密码不一致!');
      return;
    }
    console.log(state);
    dispatch({ type: 'reset' });
  };

  return (
    <form onSubmit={handleSubmit}>
      <input
        value={state.username}
        onChange={(e) => dispatch({ type: 'updateField', field: 'username', value: e.target.value })}
        placeholder="用户名"
      />
      <input
        value={state.email}
        onChange={(e) => dispatch({ type: 'updateField', field: 'email', value: e.target.value })}
        placeholder="邮箱"
      />
      <input
        type="password"
        value={state.password}
        onChange={(e) => dispatch({ type: 'updateField', field: 'password', value: e.target.value })}
        placeholder="密码"
      />
      <input
        type="password"
        value={state.confirmPassword}
        onChange={(e) => dispatch({ type: 'updateField', field: 'confirmPassword', value: e.target.value })}
        placeholder="确认密码"
      />
      <label>
        <input
          type="checkbox"
          checked={state.acceptTerms}
          onChange={(e) => dispatch({ type: 'updateField', field: 'acceptTerms', value: e.target.checked })}
        />
        同意条款
      </label>
      <button type="submit">注册</button>
      <button type="button" onClick={() => dispatch({ type: 'reset' })}>重置</button>
    </form>
  );
}

特点

  • 所有字段集中管理在 state
  • 重置、动态字段处理方便。
  • 更新逻辑统一在 reducer,可维护性高。

总结 : 为什么要用 useReducer

  • 当你有多个状态值 要管理,且它们之间有关联(比如同时更新多个字段)
  • 当更新逻辑复杂,用 useState 会很混乱
  • 想让状态更新逻辑更清晰、集中、可测试
相关推荐
0思必得01 天前
[Web自动化] Selenium处理动态网页
前端·爬虫·python·selenium·自动化
东东5161 天前
智能社区管理系统的设计与实现ssm+vue
前端·javascript·vue.js·毕业设计·毕设
catino1 天前
图片、文件的预览
前端·javascript
layman05281 天前
webpack5 css-loader:从基础到原理
前端·css·webpack
半桔1 天前
【前端小站】CSS 样式美学:从基础语法到界面精筑的实战宝典
前端·css·html
AI老李1 天前
PostCSS完全指南:功能/配置/插件/SourceMap/AST/插件开发/自定义语法
前端·javascript·postcss
_OP_CHEN1 天前
【前端开发之CSS】(一)初识 CSS:网页化妆术的终极指南,新手也能轻松拿捏页面美化!
前端·css·html·网页开发·样式表·界面美化
啊哈一半醒1 天前
CSS 主流布局
前端·css·css布局·标准流 浮动 定位·flex grid 响应式布局
PHP武器库1 天前
ULUI:不止于按钮和菜单,一个专注于“业务组件”的纯 CSS 框架
前端·css
电商API_180079052471 天前
第三方淘宝商品详情 API 全维度调用指南:从技术对接到生产落地
java·大数据·前端·数据库·人工智能·网络爬虫