React中基于useReducer实现点击按钮展示筛选后待办事项状态的技术咨询
实现Todo筛选渲染的思路和代码优化
Hey,我来帮你搞定这个筛选切换的问题!其实核心思路就是用一个状态跟踪当前选中的筛选类型,然后根据这个类型动态渲染对应的待办列表,而且咱们还能优化一下你现在的状态结构,避免冗余~
步骤1:添加筛选状态
首先在组件里加一个状态,用来记录当前用户选择的筛选类型(全部/活跃/已完成):
import { useState, useReducer, useMemo } from 'react'; // ... 其他代码 export default function TodosState() { const [todosState, dispatchTodos] = useReducer(todosReducer, todosInitalState); // 新增筛选状态,默认显示全部 const [filter, setFilter] = useState('all'); const uncheckedTodos = todosState.todos.filter(todo => !todo.completed); // ... 其他代码 }
步骤2:给筛选按钮绑定状态更新事件
给三个筛选按钮加上点击事件,点击时更新filter状态,还可以给选中的按钮加个高亮样式提升体验:
<div className={styles.buttons}> <button onClick={() => setFilter('all')} className={filter === 'all' ? styles.active : ''} > All </button> <button onClick={() => setFilter('active')} className={filter === 'active' ? styles.active : ''} > Active </button> <button onClick={() => setFilter('completed')} className={filter === 'completed' ? styles.active : ''} > Completed </button> </div>
(styles.active是可选的自定义样式类,你可以根据自己的CSS需求调整高亮效果)
步骤3:根据筛选状态动态计算要渲染的列表
你原来的状态里维护了activeTodos和completedTodos,其实完全可以不用存这两个数组——每次根据主todos数组和当前filter动态过滤就行,这样能避免状态同步的麻烦(比如修改todo的completed状态时,不用同时更新三个数组)。
用useMemo做缓存,避免每次渲染都重复过滤:
// 根据筛选状态动态计算要显示的todo列表 const filteredTodos = useMemo(() => { switch(filter) { case 'active': return todosState.todos.filter(todo => !todo.completed); case 'completed': return todosState.todos.filter(todo => todo.completed); default: // 'all' return todosState.todos; } }, [filter, todosState.todos]); // 依赖项变化时才重新计算
步骤4:渲染过滤后的列表
把原来渲染todosState.todos的地方换成filteredTodos就行:
<ul> {filteredTodos.map((todo) => { return ( <TodoItem key={todo.id} id={todo.id} text={todo.todoValue} onCheck={saveCheckedValues} ></TodoItem> ); })} </ul>
额外优化:简化初始状态
既然不再需要维护activeTodos和completedTodos,可以把初始状态简化成只保留主todos数组:
const todosInitalState = { todos: [ {todoValue: "exampleTodo", id: 3.14, completed: false}, {todoValue: "exampleTodoNo2", id: 42, completed: true} ] };
这样你的reducer逻辑也能更简洁,不用处理三个数组的同步啦~
这样一来,点击不同的筛选按钮,就会自动切换渲染对应状态的待办事项了!
内容的提问来源于stack exchange,提问作者Ayhan
相关产品推荐
相关产品推荐

