ReactJS中基于星期几的待办事项分栏展示:除条件渲染外的最优实现方案
更优的按星期分组展示Todo的React实现方案
嘿,看起来你已经搞定了基础的条件渲染实现,不过确实有更简洁高效的方案,能帮你减少冗余代码、提升可维护性,我挑两个实用的给你说说:
1. 先预处理数据:按星期分组再渲染
条件渲染的问题在于每一列都要写一次过滤逻辑,代码重复还麻烦。不如先把Todo列表按created_at分组,之后直接循环渲染对应分组的内容就行。
实现步骤:
- 用
reduce把原始Todo数组转换成以星期几为key,对应Todo数组为value的对象 - 定义固定的星期顺序数组(保证列的顺序不会乱)
- 循环星期数组,取出对应分组的Todo渲染
代码示例:
import { useMemo } from 'react'; const TodoApp = ({ todos }) => { // 用useMemo缓存分组结果,避免每次渲染都重新计算(性能优化) const groupedTodos = useMemo(() => { return todos.reduce((acc, todo) => { const day = todo.created_at; // 如果当前星期还没在分组里,初始化一个空数组 if (!acc[day]) { acc[day] = []; } acc[day].push(todo); return acc; }, {}); }, [todos]); // 固定星期顺序,保证列的展示顺序正确 const daysOfWeek = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]; return ( <div className="todo-container"> <h1>Weekly Todos</h1> <div className="todo-grid"> {daysOfWeek.map(day => ( <div key={day} className="todo-column"> <h3>{day}</h3> {/* 取出当前星期的Todo,没有的话显示提示 */} {groupedTodos[day]?.length ? ( groupedTodos[day].map(todo => ( <div key={todo.name} className="todo-item"> {todo.name} </div> )) ) : ( <p className="empty-todo">No todos for {day}</p> )} </div> ))} </div> </div> ); };
2. 抽象成独立组件:每列对应一个组件
如果觉得直接分组还不够灵活,可以把“星期列”抽象成一个独立组件,让组件自己负责过滤对应星期的Todo,父组件只需要传参就行。这种方式更符合React的组件化思想,后续修改列的样式或逻辑也更方便。
实现步骤:
- 创建
WeekDayTodoColumn组件,接收day和todos两个props - 组件内部过滤出对应星期的Todo并渲染
- 父组件循环星期数组,渲染每个
WeekDayTodoColumn
代码示例:
import { useMemo } from 'react'; // 独立的星期列组件 const WeekDayTodoColumn = ({ day, todos }) => { // 缓存过滤结果,优化性能 const dayTodos = useMemo(() => { return todos.filter(todo => todo.created_at === day); }, [todos, day]); return ( <div className="todo-column"> <h3>{day}</h3> {dayTodos.length ? ( dayTodos.map(todo => ( <div key={todo.name} className="todo-item"> {todo.name} </div> )) ) : ( <p className="empty-todo">No todos for {day}</p> )} </div> ); }; // 主应用组件 const TodoApp = ({ todos }) => { const daysOfWeek = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]; return ( <div className="todo-container"> <h1>Weekly Todos</h1> <div className="todo-grid"> {daysOfWeek.map(day => ( <WeekDayTodoColumn key={day} day={day} todos={todos} /> ))} </div> </div> ); };
为什么这两个方案比条件渲染好?
- 减少代码冗余:不用写7次几乎一样的条件判断,修改逻辑只需要改一处
- 更好的可维护性:调整星期顺序只需要修改
daysOfWeek数组,新增功能(比如标记完成)也更容易扩展 - 性能更优:配合
useMemo缓存计算结果,避免不必要的重渲染
内容的提问来源于stack exchange,提问作者Wani
相关产品推荐
相关产品推荐

