Day9--字节跳动-使用React 实现一个简单的待办事项列表:用户可以添加、编辑和删除待办事项|青训营

223 阅读3分钟

效果图

image.png

一、创建一个待办事项列表组件(比如 TodoList.js):

import React, { useState } from 'react';
import './TodoList.css'; // 导入自定义的CSS样式

function TodoList() {
  const [todos, setTodos] = useState([]);
  const [newTodo, setNewTodo] = useState('');
  const [editIndex, setEditIndex] = useState(-1);

  const addTodo = () => {
    if (newTodo.trim() !== '') {
      if (editIndex === -1) {
        setTodos([...todos, newTodo]);
      } else {
        const updatedTodos = [...todos];
        updatedTodos[editIndex] = newTodo;
        setTodos(updatedTodos);
        setEditIndex(-1);
      }
      setNewTodo('');
    }
  };

  const editTodo = (index) => {
    setNewTodo(todos[index]);
    setEditIndex(index);
  };

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

  return (
    <div className="todo-list">
      <h1>待办事项列表</h1>
      <div className="todo-input">
        <input
          type="text"
          placeholder="输入待办事项"
          value={newTodo}
          onChange={(e) => setNewTodo(e.target.value)}
        />
        <button onClick={addTodo}>{editIndex === -1 ? '添加' : '保存'}</button>
      </div>
      <ul>
        {todos.map((todo, index) => (
          <li key={index}>
            {todo}
            <button onClick={() => editTodo(index)}>编辑</button>
            <button onClick={() => deleteTodo(index)}>删除</button>
          </li>
        ))}
      </ul>
    </div>
  );
}

export default TodoList;

这里首先是引入了 ReactuseState 这两个从 react 库中导入的模块。同时,通过 import './TodoList.css'; 导入了自定义的CSS样式文件。

function TodoList() {
  const [todos, setTodos] = useState([]);
  const [newTodo, setNewTodo] = useState('');
  const [editIndex, setEditIndex] = useState(-1);

这段代码定义了一个名为 TodoList 的函数组件。在组件内部使用了 useState 钩子来创建了三个状态变量:

  • todos: 用于存储待办事项的数组。
  • newTodo: 用于存储用户正在输入的新待办事项。
  • editIndex: 用于跟踪正在编辑的待办事项的索引。初始值为 -1,表示没有任何事项正在被编辑。
const addTodo = () => {
  if (newTodo.trim() !== '') {
    if (editIndex === -1) {
      setTodos([...todos, newTodo]);
    } else {
      const updatedTodos = [...todos];
      updatedTodos[editIndex] = newTodo;
      setTodos(updatedTodos);
      setEditIndex(-1);
    }
    setNewTodo('');
  }
};

这是一个用于添加待办事项的函数。首先,它检查 newTodo 是否包含非空字符。如果是,它会判断当前是添加新事项还是编辑已有事项(通过 editIndex 的值来判断)。如果是添加,就将新事项添加到 todos 数组中。如果是编辑,它会更新已有事项的内容。无论是添加还是编辑,都会将 newTodo 清空,并将 editIndex 重置为 -1。


const editTodo = (index) => {
  setNewTodo(todos[index]);
  setEditIndex(index);
};

这是一个用于编辑待办事项的函数。当用户点击编辑按钮时,它会将选定的待办事项的内容赋值给 newTodo,同时将 editIndex 设置为选定待办事项的索引,以便稍后知道哪个事项正在被编辑。

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

这个函数用于删除待办事项。它使用 filter 方法来创建一个新的 todos 数组,其中排除了被选中索引的待办事项。然后,通过 setTodos 更新了 todos 状态。

return (
  <div className="todo-list">
    <h1>待办事项列表</h1>
    <div className="todo-input">
      <input
        type="text"
        placeholder="输入待办事项"
        value={newTodo}
        onChange={(e) => setNewTodo(e.target.value)}
      />
      <button onClick={addTodo}>{editIndex === -1 ? '添加' : '保存'}</button>
    </div>
    <ul>
      {todos.map((todo, index) => (
        <li key={index}>
          {todo}
          <button onClick={() => editTodo(index)}>编辑</button>
          <button onClick={() => deleteTodo(index)}>删除</button>
        </li>
      ))}
    </ul>
  </div>
);

在组件的返回部分,定义了待办事项列表的呈现方式。使用 JSX 来渲染了一个包含输入框、添加/保存按钮、待办事项列表以及编辑和删除按钮的界面。

  • 输入框 (<input>) 显示用户可以输入新待办事项的内容,value 属性绑定到 newTodo 状态,onChange 事件用于更新 newTodo
  • 添加/保存按钮根据 editIndex 的值,显示为 "添加" 或 "保存"。
  • 待办事项列表通过 todos.map 方法来渲染,每个事项都有一个编辑和删除按钮,它们会调用相应的 editTododeleteTodo 函数。

二、TodoList.css

.todo-list {
  text-align: center;
  font-family: Arial, sans-serif;
  margin: 20px auto;
  width: 300px;
  border: 1px solid #ddd;
  padding: 20px;
  border-radius: 5px;
  box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.3);
}

.todo-input {
  margin-bottom: 10px;
}

.todo-input input {
  padding: 5px;
  width: 60%;
  border-radius: 5px;
  border: 1px solid #ddd;
}

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

ul {
  list-style: none;
  padding: 0;
}

li {
  display: flex;
  justify-content: space-between;
  align-items: center;
  border-bottom: 1px solid #ddd;
  padding: 5px 0;
}

li button {
  padding: 3px 6px;
  border: none;
  background-color: #dc3545;
  color: #fff;
  border-radius: 5px;
  cursor: pointer;
  margin-left: 5px;
}

li button.edit {
  background-color: #ffc107;
  margin-right: 5px;
}

三、App.js

import React from 'react';
import TodoList from './TodoList';
import './App.css';

function App() {
  return (
    <div className="app">
      <TodoList />
    </div>
  );
}

export default App;