当前位置: 首页 > news >正文

react 使用 Reducer 和 Context 进行纵向扩展

Reducer 允许您合并组件的状态更新逻辑。上下文允许您将信息深入传递到其他组件。您可以将 reducer 和 context 组合在一起,以管理复杂屏幕的状态。

将减速器与上下文相结合

在 reducer 简介中的此示例中,状态由 reducer 管理。reducer 函数包含所有状态更新逻辑,并在以下文件底部声明:

import { useReducer } from 'react';
import AddTask from './AddTask.js';
import TaskList from './TaskList.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>Day off in Kyoto</h1><AddTaskonAddTask={handleAddTask}/><TaskListtasks={tasks}onChangeTask={handleChangeTask}onDeleteTask={handleDeleteTask}/></>);
}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('Unknown action: ' + action.type);}}
}let nextId = 3;
const initialTasks = [{ id: 0, text: 'Philosopher’s Path', done: true },{ id: 1, text: 'Visit the temple', done: false },{ id: 2, text: 'Drink matcha', done: false }
];
import { useState } from 'react';export default function AddTask({ onAddTask }) {const [text, setText] = useState('');return (<><inputplaceholder="Add task"value={text}onChange={e => setText(e.target.value)}/><button onClick={() => {setText('');onAddTask(text);}}>Add</button></>)
}
import { useState } from 'react';export default function TaskList({tasks,onChangeTask,onDeleteTask
}) {return (<ul>{tasks.map(task => (<li key={task.id}><Tasktask={task}onChange={onChangeTask}onDelete={onDeleteTask}/></li>))}</ul>);
}function Task({ task, onChange, onDelete }) {const [isEditing, setIsEditing] = useState(false);let taskContent;if (isEditing) {taskContent = (<><inputvalue={task.text}onChange={e => {onChange({...task,text: e.target.value});}} /><button onClick={() => setIsEditing(false)}>Save</button></>);} else {taskContent = (<>{task.text}<button onClick={() => setIsEditing(true)}>Edit</button></>);}return (<label><inputtype="checkbox"checked={task.done}onChange={e => {onChange({...task,done: e.target.checked});}}/>{taskContent}<button onClick={() => onDelete(task.id)}>Delete</button></label>);
}

reducer 有助于使事件处理程序保持简短。但是,随着应用的增长,您可能会遇到另一个困难。目前,任务状态和调度功能仅在顶级 TaskApp 组件中可用。若要让其他组件读取任务列表或更改它,必须显式传递当前状态和更改它的事件处理程序作为道具。

例如,将任务列表和事件处理程序传递给:TaskAppTaskList

<TaskList
tasks={tasks}
onChangeTask={handleChangeTask}
onDeleteTask={handleDeleteTask}
/>

并将事件处理程序传递给:TaskListTask

<Task
task={task}
onChange={onChangeTask}
onDelete={onDeleteTask}
/>

在像这样的小例子中,这很有效,但是如果你中间有几十个或几百个组件,那么传递所有状态和函数可能会非常令人沮丧!

相关文章:

  • 安全攻防三
  • 29【PS 作图】宫灯 夜景转换
  • SCP收容物191~200
  • [Android]将私钥(.pk8)和公钥证书(.pem/.crt)合并成一个PKCS#12格式的密钥库文件
  • 周末总结(2024/05/25)
  • spring cloud config server源码学习(一)
  • 用天工AI写文章,节约了8个人的成本
  • 前端Vue小兔鲜儿电商项目实战Day01
  • 7个靠谱的副业赚钱方法,宝妈,上班族,学生党可以做的兼职副业
  • Debug-011-ES6中的链判断运算符(?.)
  • 前端自动将 HTTP 请求升级为 HTTPS 请求
  • Vue3实战笔记(37)—粒子特效登录页面
  • React@16.x(11)ref
  • OrangePi AIpro (8T)使用体验,性能测试报告
  • 【前端学习笔记】HTML基础
  • 《用数据讲故事》作者Cole N. Knaflic:消除一切无效的图表
  • 【每日笔记】【Go学习笔记】2019-01-10 codis proxy处理流程
  • Git 使用集
  • Webpack入门之遇到的那些坑,系列示例Demo
  • webpack项目中使用grunt监听文件变动自动打包编译
  • 百度小程序遇到的问题
  • 从0到1:PostCSS 插件开发最佳实践
  • 码农张的Bug人生 - 见面之礼
  • 如何选择开源的机器学习框架?
  • 收藏好这篇,别再只说“数据劫持”了
  • 正则表达式
  • 【干货分享】dos命令大全
  • 格斗健身潮牌24KiCK获近千万Pre-A轮融资,用户留存高达9个月 ...
  • ​​​​​​​ubuntu16.04 fastreid训练过程
  • #HarmonyOS:Web组件的使用
  • #php的pecl工具#
  • #我与Java虚拟机的故事#连载18:JAVA成长之路
  • (11)MSP430F5529 定时器B
  • (2)(2.10) LTM telemetry
  • (c语言)strcpy函数用法
  • (C语言)共用体union的用法举例
  • (LeetCode) T14. Longest Common Prefix
  • (Redis使用系列) Springboot 在redis中使用BloomFilter布隆过滤器机制 六
  • (TipsTricks)用客户端模板精简JavaScript代码
  • (附源码)spring boot车辆管理系统 毕业设计 031034
  • (附源码)springboot 校园学生兼职系统 毕业设计 742122
  • (附源码)计算机毕业设计ssm基于Internet快递柜管理系统
  • (函数)颠倒字符串顺序(C语言)
  • (十八)SpringBoot之发送QQ邮件
  • (四) 虚拟摄像头vivi体验
  • (一)eclipse Dynamic web project 工程目录以及文件路径问题
  • (原創) 如何解决make kernel时『clock skew detected』的warning? (OS) (Linux)
  • (转)jQuery 基础
  • .NET Core中Emit的使用
  • .netcore 6.0/7.0项目迁移至.netcore 8.0 注意事项
  • .NET单元测试
  • .NET性能优化(文摘)
  • .sys文件乱码_python vscode输出乱码
  • @Autowired @Resource @Qualifier的区别
  • @Bean注解详解