react时空之城计划本


界面展示

首页

内容

演示视频:

【五分钟教你用react做一个小项目-日程清单】 https://www.bilibili.com/video/BV1K4B4Y9ErZ/

研发意义

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

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

设计思路

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

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

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

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

步骤

布局

  1. 组件结构
    • 组件包含一个输入框和两个按钮,用于添加新的待办事项和批量删除已选中的待办事项。
    • 里面包含一个无序列表,用于显示所有的待办事项。
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      60
      61
      62
      63
      64
      65
      66
      67


      return (

      <div>

      <input

      type="text"

      value={newPlanText}

      onChange={e => setNewPlanText(e.target.value)}

      />

      <button onClick={addPlan}>新增</button>

      <button onClick={deleteSelectedPlans} disabled={selectedPlans.length === 0}>

      批量删除

      </button>

      <ul className='daily_ul'>

      {plans.map(plan => (

      <li key={plan.id} className='daily_li'>

      <input

      type="checkbox"

      className='daily_checkbox'

      checked={selectedPlans.includes(plan.id)}

      onChange={() => toggleSelectPlan(plan.id)}

      />

      <input

      type="text"

      value={plan.text}

      onChange={e => updatePlanText(plan.id, e.target.value)}

      style={{ textDecoration: plan.completed ? 'line-through' : 'none' }}

      />

      <button onClick={() => deletePlan(plan.id)}>删除</button>

      <button onClick={() => toggleCompletion(plan.id)}>{plan.completed ? '未完成' : '已完成'}</button>

      </li>

      ))}

      </ul>

      </div>

      );

初始化数据

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

  • plans:用于存储待办事项列表,初始值为 list
  • newPlanText:用于存储新待办事项的文本,初始值为空字符串。
  • selectedPlans:用于存储选中的待办事项的 ID,初始值为空数组。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
  

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 重置为空字符串,以便用户可以输入下一个新的计划。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
const addPlan = () => {

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

const newPlan: Plan = {

id: Date.now(),

text: newPlanText,

completed: false,

};

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

setNewPlanText('');

}

};

删除事项

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

1
2
3
4
5
6
7
8
9
10
11
12
13
const deletePlan = (id: number) => {

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

};

const deleteSelectedPlans = () => {

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

setSelectedPlans([]);

};

点击勾选框

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

1
2
3
4
5
6
7
8
9
10
11
12
13
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 更新计划项的文本内容。它通过遍历计划项列表,找到匹配的计划项并更新其文本内容,然后返回更新后的计划项列表。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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来避免不必要的渲染。

开源地址

https://github.com/Charlotte21110/TodoList


文章作者: 悠然寂夏
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 悠然寂夏 !
评论
评论
评论
  目录