前端实践|react时空之城计划本| 豆包MarsCode AI刷题

100 阅读5分钟

界面展示

界面1.png

界面2.png

研发初衷

在现代社会中,时间管理和任务规划对于个人和团队的效率和生产力至关重要。随着工作和生活节奏的加快,人们需要一种简单而有效的方式来管理他们的日常计划。为了满足这一需求,我写了一个名为“时空之城计划本”的小项目,它提供了一个直观的界面,用于创建、编辑、删除日常任务事项。

这个项目用react + vite去做的~

设计思路

组件化设计:将整个应用程序拆分为多个组件,每个组件负责特定的功能,如输入框、按钮、列表项等,以提高代码的可维护性和复用性。

状态管理:使用React的useState钩子来管理组件的状态,包括任务列表、新任务文本和选中的任务ID,确保状态的更新是响应式的。

事件处理:为每个交互元素(如按钮、输入框)添加事件处理函数,以响应用户的操作,如添加新任务、删除任务、标记完成等。

样式设计:使用CSS模块来管理组件的样式,确保样式的独立性和可维护性,同时提供良好的用户体验。

步骤

布局

组件结构: - 组件包含一个输入框和两个按钮,用于添加新的待办事项和批量删除已选中的待办事项。 - 里面包含一个无序列表,用于显示所有的待办事项。

一个简洁的tsx布局

image.png

放上一点css

image.png

初始化数据

这里定义了一个名为 list 的常量,它是一个包含一些初始待办事项的数组。然后,使用 useState 钩子定义了三个状态变量:

  • plans:用于存储待办事项列表,初始值为 list
  • newPlanText:用于存储新待办事项的文本,初始值为空字符串。
  • selectedPlans:用于存储选中的待办事项的 ID,初始值为空数组。
  

const DailyPlan: React.FC = () => {

  const list = [

    { id: 1, text: '学习React', completed: false },

    { id: 2, text: '学习Vue', completed: true },

    { id: 3, text: '学习Angular', completed: false },

    { id: 4, text: '学习JavaScript', completed: true },

    { id: 5, text: '学习TypeScript', completed: false },

  ]

  const [plans, setPlans] = useState<Plan[]>(list);

  const [newPlanText, setNewPlanText] = useState('');

  const [selectedPlans, setSelectedPlans] = useState<number[]>([]);

添加事项

  1. 它检查 newPlanText 是否为空或只包含空格。trim() 方法用于去除字符串两端的空格,如果去除空格后的字符串不为空,则执行下一步。
  2. 然后,它创建一个新的 Plan 对象 newPlan,其中包含当前时间戳作为 ID,newPlanText 作为文本内容,以及 completed 状态为 false
  3. 使用 setPlans 函数更新 plans 状态,将新的计划对象添加到现有的计划列表中。[...plans, newPlan] 是一种扩展运算符的用法,它将现有的 plans 数组展开,并将 newPlan 添加到数组的末尾。
  4. 将 newPlanText 重置为空字符串,以便用户可以输入下一个新的计划。
const addPlan = () => {

    if (newPlanText.trim() !== '') {

      const newPlan: Plan = {

        id: Date.now(),

        text: newPlanText,

        completed: false,

      };

      setPlans([...plans, newPlan]);

      setNewPlanText('');

    }

  };

删除事项

用过滤的方法,重新给计划Plans去赋值,针对单个和多个的情况

  const deletePlan = (id: number) => {

    setPlans(plans.filter(plan => plan.id !== id));

  };
   
   const deleteSelectedPlans = () => {

    setPlans(plans.filter(plan => !selectedPlans.includes(plan.id)));

    setSelectedPlans([]);

  };

点击勾选框

写一个函数用于在选中的计划项列表中添加或移除指定的计划项,从而实现选择和取消选择的功能。

  • 使用 setSelectedPlans 更新 selectedPlans 状态。

  • prevSelectedPlans 是当前选中的计划项的 ID 列表。

  • 检查 prevSelectedPlans 是否包含传入的 id

    • 如果包含(即该计划项已经被选中),则通过 filter 方法移除该 id,从而取消选择该计划项。
    • 如果不包含(即该计划项未被选中),则通过展开运算符 ... 将 id 添加到 prevSelectedPlans 中,从而选择该计划项。
  const toggleSelectPlan = (id: number) => {

    setSelectedPlans(prevSelectedPlans =>

      prevSelectedPlans.includes(id)

        ? prevSelectedPlans.filter(planId => planId !== id)

        : [...prevSelectedPlans, id]

    );

  };

更新事项

  1. 参数

    • id:一个数字,表示要更新的计划项的唯一标识符。
    • newText:一个字符串,表示新的文本内容。
  2. 逻辑

    • 使用 setPlans 更新 plans 状态。
    • plans.map 遍历当前所有的计划项。
    • 对于每个计划项 plan,检查其 id 是否等于传入的 id
      • 如果相等,表示找到了需要更新的计划项,返回一个新的对象,该对象包含原计划项的所有属性(通过展开运算符 ...plan),但 text 属性被更新为 newText
      • 如果不相等,表示该计划项不需要更新,直接返回原计划项。

这个函数用于根据指定的 id 更新计划项的文本内容。它通过遍历计划项列表,找到匹配的计划项并更新其文本内容,然后返回更新后的计划项列表。

const updatePlanText = (id: number, newText: string) => {

  setPlans(plans.map(plan => {

    if (plan.id === id) {

      return {

        ...plan,

        text: newText,

      };

    }

    return plan;

  }));

};

学习感悟

在学习这个demo的过程中,我深刻体会到了React框架的强大和灵活性。

组件化思维:React的组件化思想让代码更加模块化和可重用。DailyPlan组件被设计为一个独立的功能单元,可以轻松地在不同的应用程序中复用。

状态管理:通过useState钩子,我们可以轻松地管理组件的状态。我们使用useState来管理待办事项列表、新计划的文本以及选中的计划。这种方式使得状态的更新和管理变得简单直观。

事件处理:React的事件处理机制非常简洁高效。我们通过onClickonChange等事件处理函数来响应用户的交互,如添加新计划、删除计划、切换计划的完成状态等。

条件渲染:React的条件渲染允许我们根据组件的状态来决定渲染的内容。使用条件渲染来显示或隐藏批量删除按钮,以及根据计划的完成状态来添加删除线样式。

列表渲染:使用map方法来渲染列表是React中的常见模式。通过plans.map来遍历待办事项列表,并为每个计划渲染一个<li>元素。

函数式编程:React鼓励使用函数式编程的思想,如使用filtermap等高阶函数来处理数组。

另外的就是一点提升空间:在编写DailyPlan组件时,需要考虑代码的性能和可维护性。例如,可以使用useMemouseCallback来优化性能,使用React.memoReact.PureComponent来避免不必要的渲染。