使用React实现一个简单的待办事项列表(方向三前端实践选题)

129 阅读4分钟

引言

在前端开发中,待办事项列表(To-Do List)是一个非常常见的应用案例。它不仅能够帮助用户管理日常任务,还是学习和展示前端技术的绝佳平台。本文将通过一个具体的项目实例——使用React实现一个简单的待办事项列表,来探讨如何利用现代前端技术构建实用且高效的Web应用。

项目概述

我们的待办事项列表应用将具备以下功能:

  1. 添加待办事项:用户可以输入新的待办事项并将其添加到列表中。
  2. 编辑待办事项:用户可以修改已有的待办事项内容。
  3. 删除待办事项:用户可以从列表中移除不需要的待办事项。
  4. 标记完成状态:用户可以标记待办事项为已完成或未完成。

我们将使用React框架来构建这个应用,并结合CSS进行样式设计,同时还会涉及到一些性能优化技巧。

技术栈

React:用于构建用户界面的主要框架。

JavaScript:编写逻辑处理和事件响应。

CSS:用于美化界面。

HTML5:提供基础的文档结构。

项目搭建

首先,我们需要创建一个新的React应用。如果你还没有安装create-react-app工具,可以通过npm安装它:

bash
深色版本
npx create-react-app todo-list
cd todo-list

这将生成一个基本的React项目结构。接下来,我们将在src目录下创建必要的文件和组件。

组件设计

我们的待办事项列表应用主要由以下几个组件构成:

App:主组件,负责整个应用的状态管理和渲染子组件。

TodoInput:输入框组件,用于添加新的待办事项。

TodoItem:单个待办事项项组件,包含编辑、删除等功能。

TodoList:列表组件,显示所有待办事项。

App.js
jsx
深色版本
import React, { useState } from 'react';
import TodoInput from './components/TodoInput';
import TodoList from './components/TodoList';

function App() {
  const [todos, setTodos] = useState([]);

  const addTodo = (text) => {
    setTodos([...todos, { text, completed: false }]);
  };

  const toggleComplete = (index) => {
    const newTodos = [...todos];
    newTodos[index].completed = !newTodos[index].completed;
    setTodos(newTodos);
  };

  const deleteTodo = (index) => {
    setTodos(todos.filter((_, i) => i !== index));
  };

  return (
    <div className="app">
      <h1>待办事项列表</h1>
      <TodoInput onAdd={addTodo} />
      <TodoList 
        todos={todos} 
        onToggle={toggleComplete} 
        onDelete={deleteTodo} 
      />
    </div>
  );
}

export default App;
TodoInput.js
jsx
深色版本
import React, { useState } from 'react';

const TodoInput = ({ onAdd }) => {
  const [input, setInput] = useState('');

  const handleAdd = () => {
    if (input.trim()) {
      onAdd(input);
      setInput('');
    }
  };

  return (
    <div className="todo-input">
      <input
        type="text"
        value={input}
        onChange={(e) => setInput(e.target.value)}
        placeholder="添加新任务..."
      />
      <button onClick={handleAdd}>添加</button>
    </div>
  );
};

export default TodoInput;
TodoList.js
jsx
深色版本
import React from 'react';
import TodoItem from './TodoItem';

const TodoList = ({ todos, onToggle, onDelete }) => {
  return (
    <ul className="todo-list">
      {todos.map((todo, index) => (
        <TodoItem
          key={index}
          todo={todo}
          index={index}
          onToggle={onToggle}
          onDelete={onDelete}
        />
      ))}
    </ul>
  );
};

export default TodoList;
TodoItem.js
jsx
深色版本
import React, { useState } from 'react';

const TodoItem = ({ todo, index, onToggle, onDelete }) => {
  const [isEditing, setIsEditing] = useState(false);
  const [editText, setEditText] = useState(todo.text);

  const handleEdit = () => {
    setIsEditing(true);
  };

  const handleSave = () => {
    if (editText.trim()) {
      onToggle(index); // 这里假设保存时也切换完成状态
      setIsEditing(false);
    }
  };

  const handleChange = (e) => {
    setEditText(e.target.value);
  };

  return (
    <li className={`todo-item ${todo.completed ? 'completed' : ''}`}>
      {isEditing ? (
        <input
          type="text"
          value={editText}
          onChange={handleChange}
          onBlur={handleSave}
        />
      ) : (
        <>
          <span onClick={() => onToggle(index)}>{todo.text}</span>
          <button onClick={handleEdit}>编辑</button>
          <button onClick={() => onDelete(index)}>删除</button>
        </>
      )}
    </li>
  );
};

export default TodoItem;

样式设计

为了使应用看起来更美观,我们可以添加一些CSS样式。例如,在src/index.css中加入以下样式:

css
深色版本
.app {
  font-family: Arial, sans-serif;
  max-width: 400px;
  margin: auto;
  padding: 20px;
}

.todo-input {
  display: flex;
  justify-content: space-between;
  margin-bottom: 20px;
}

.todo-input input {
  width: 70%;
  padding: 10px;
  border: 1px solid #ccc;
  border-radius: 4px;
}

.todo-input button {
  padding: 10px 20px;
  background-color: #007bff;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

.todo-list {
  list-style: none;
  padding: 0;
}

.todo-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px;
  border: 1px solid #ddd;
  border-radius: 4px;
  margin-bottom: 10px;
}

.todo-item.completed span {
  text-decoration: line-through;
}

.todo-item input {
  width: 100%;
  padding: 5px;
  border: 1px solid #ccc;
  border-radius: 4px;
}

性能优化

为了提高应用的性能,我们可以采取以下措施:

减少不必要的重绘和重排:通过使用React.memo来包裹纯函数组件,避免不必要的重新渲染。

使用节流和防抖技术:如果需要处理频繁触发的事件(如窗口大小变化),可以使用Lodash库中的throttledebounce方法。

使用性能分析工具:利用Chrome DevTools中的Performance面板来检测和优化性能瓶颈。

结论

通过上述步骤,我们成功地使用React实现了一个简单的待办事项列表应用。这个过程不仅展示了React的基本用法,还涉及到了组件化思维、状态管理以及一些性能优化技巧。希望这个案例能够帮助你更好地理解和掌握React框架,并在实际项目中灵活运用这些知识。随着经验的积累,你可以尝试添加更多高级功能,如数据持久化、拖拽排序等,以进一步提升用户体验。