You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 21:47:47