图文并茂五分钟搞懂react中的reducer

图文并茂五分钟搞懂react中的reducerReducer 是处理状态的另一种方式

大家好,欢迎来到IT知识分享网。

什么是 reducer 函数? 为什么要用 reducer?

  • Reducer 是处理状态的另一种方式。通俗来讲,就是可以让你的复杂组件更加干净,代码更加优雅
  • 当你的组件里有好多个状态更新逻辑,并且有些是有一定关联性的,写多个useState会看起来很杂乱,为解决这个问题,我们可以将多个状态更新逻辑整合到一个外部函数,这个函数就是reducer
  • 整合业务逻辑

使用 reducer 整合状态逻辑

举个栗子:

图文并茂五分钟搞懂react中的reducer
从上图我们可以看到,目前这个组件有三个处理逻辑,我们写了三个处理函数,这个组件的每个事件处理程序都通过 setTasks 来更新状态。随着这个组件的不断迭代,其状态逻辑也会越来越多。现在看起来没有什么毛病,但是真实业务场景里,需求往往会更加复杂,我们可以使用下面的方式来让业务逻辑更加清晰明了:

将状态逻辑移到组件之外 reducer 函数中
  • 将设置状态的逻辑 修改 成 dispatch 的一个 action;
  • 编写 一个 reducer 函数;
  • 在你的组件中 使用 reducer

图文并茂五分钟搞懂react中的reducer

看了上面我画的图,是不是感觉reducer很简单哇~ 在真实项目中,我们通常会使用 switch 语句来编写reducer,就像下图

图文并茂五分钟搞懂react中的reducer

既然我们会写了,那该怎么使用呢?
图文并茂五分钟搞懂react中的reducer

代码

tasksReducer.js

export default function tasksReducer(tasks, action) { switch (action.type) { case 'added': { return [ ...tasks, { id: action.id, text: action.text, done: false, }, ]; } case 'changed': { return tasks.map((t) => { if (t.id === action.task.id) { return action.task; } else { return t; } }); } case 'deleted': { return tasks.filter((t) => t.id !== action.id); } default: { throw Error('未知 action:' + action.type); } } } 

App.js

import { useReducer } from 'react'; import AddTask from './AddTask.js'; import TaskList from './TaskList.js'; import tasksReducer from './tasksReducer.js'; export default function TaskApp() { const [tasks, dispatch] = useReducer(tasksReducer, initialTasks); function handleAddTask(text) { dispatch({ type: 'added', id: nextId++, text: text, }); } function handleChangeTask(task) { dispatch({ type: 'changed', task: task, }); } function handleDeleteTask(taskId) { dispatch({ type: 'deleted', id: taskId, }); } return ( <> <h1>我今天要做什么呢?</h1> <AddTask onAddTask={handleAddTask} /> <TaskList tasks={tasks} onChangeTask={handleChangeTask} onDeleteTask={handleDeleteTask} /> </> ); } let nextId = 3; const initialTasks = [ {id: 0, text: '吃饭', done: true}, {id: 1, text: '睡觉', done: false}, {id: 2, text: '打豆豆', done: false}, ]; 

对比 useState 和 useReducer

图文并茂五分钟搞懂react中的reducer

我们观察上图,不难发现:

  • 参数:useReducer 和 useState 很相似,都有初始状态,useReducer 钩子接受 2 个参数: reducer 函数,初始的 state
  • 返回值:useReducer 会返回一个有状态的值和一个设置该状态的函数(在上面案例中就是 dispatch 函数)
  • 代码体积: 多事件相似方式修改 state 时,useReducer 可减少代码量
  • 可读性: 状态更新逻辑简单我们就可以用useState ,逻辑复杂,useReducer 可以将状态更新逻辑与事件处理程序分离
  • 可调试性: useState 出现问题不太好调试,而使用 useReducer 时, 可以在 reducer 函数打印日志

如何编写一个优雅的 reducer

  • reducers 必须纯粹。 即当输入相同时,输出也是相同的。它们不应该包含异步请求、定时器或者任何副作用(对组件外部有影响的操作)。
  • 每个 action 都描述了一个单一的用户交互,即使它会引发数据的多个变化。 举个例子,如果用户在一个由 reducer 管理的表单(包含五个表单项)中点击了 重置按钮,那么 dispatch 一个 reset_form 的 action 比 dispatch 五个单独的 set_field 的 action 更加合理。
还可以使用 Immer 简化 reducers

useImmerReducer 让你可以通过 push 或 arr[i] = 来修改 state。下图描述了,优化前后,代码确实有所减少哦~~
图文并茂五分钟搞懂react中的reducer
Reducers 应该是纯净的,而 Immer 提供了一种特殊的 draft 对象,可以通过它安全修改 state。Immer 在底层基于当前 state 创建一个副本。

今天就写到这里啦~
  • 小伙伴们,( ̄ω ̄( ̄ω ̄〃 ( ̄ω ̄〃)ゝ我们明天再见啦~~
  • 大家要天天开心哦

在这里插入图片描述

欢迎路过的小哥哥小姐姐们提出更好的意见哇~~

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/147819.html

(0)
上一篇 2025-04-04 18:26
下一篇 2025-04-04 18:33

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信