如何使用 React Hooks 构建 React To-Do 应用程序

介绍

React是一个前端 JavaScript 库,可用于为您的应用程序创建交互式用户界面。

在本教程中,您将创建一个待办事项应用程序。您的应用程序将需要显示任务、添加新任务、将任务标记为完成并删除任务。这些操作将涉及CRUD(创建、读取、更新和删除)应用程序的四个方面

这种类型的项目通常是用 Class 组件来完成的,但是这个应用程序会集成React HooksReact Hooks 允许功能组件具有状态并使用生命周期方法,从而避免使用 Class 组件并拥有更多模块化和可读性的代码。

您可以在 CodeSandbox 上查看已完成的项目

先决条件

要完成本教程,您需要:

第 1 步 – 启动 React 应用程序

首先,您需要创建一个新应用程序。在您的终端窗口中,导航到您希望新应用程序所在的位置并键入:

  • npx create-react-app react-to-do

注意:在 React 16.8 之前,您必须安装 React 16.7 的 alpha 版本才能使用 React Hooks。在撰写本文时,Create React App将安装支持 Hooks 的最新稳定版 React (16.13.1)。

接下来,导航到新的项目目录:

  • cd react-to-do

然后,运行项目:

  • npm start

localhost:3000在浏览器中导航到旋转的 React 徽标。

您的应用程序现已设置完毕,您可以继续构建应用程序的其余部分。

第 2 步 — 设计您的应用程序

样式不是本教程的重点,但它有助于显示待办事项。

App.css在代码编辑器中打开

  • nano src/App.css

将此文件的内容替换为您将在整个应用程序中使用的三个类:

源代码/应用程序.css
.app {
  background: #209cee;
  height: 100vh;
  padding: 30px;
}

.todo-list {
  background: #e8e8e8;
  border-radius: 4px;
  max-width: 400px;
  padding: 5px;
}

.todo {
  align-items: center;
  background: #fff;
  border-radius: 3px;
  box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.15);
  display: flex;
  font-size: 12px;
  justify-content: space-between;
  margin-bottom: 6px;
  padding: 3px 10px;
}

这对于创建CSS类apptodo-listtodo它利用vh(视口高度)单位和flexbox属性(align-itemsjustify-content)。

造型完成。现在,您可以实现 CRUD 的各个方面。

第 3 步——阅读待办事项

让我们从CRUD读取部分开始您需要列出一份清单,以便您可以阅读和查看该清单。

使用类的待办事项应用程序将类似于以下内容:

class App extends Component {
  state = {
    todos: [
      { text: "Learn about React" },
      { text: "Meet friend for lunch" },
      { text: "Build really cool todo app" }
    ]
  }

  setTodos = todos => this.setState({ todos });

  render() {
    return <div></div>
  }
}

您将使用 React Hooks,因此状态看起来与使用类时略有不同。

打开App.js:

  • nano src/App.js

修改此文件以将以下行代码添加到App组件中:

源代码/App.js
import React from 'react';
import logo from './logo.svg';
import './App.css';

function App() {
  const [todos, setTodos] = React.useState([
    { text: "Learn about React" },
    { text: "Meet friend for lunch" },
    { text: "Build really cool todo app" }
  ]);

  return (
    // ...
  );
}

export default App;

该组件是一个功能组件。在过去的 React 版本中,函数式组件无法处理状态,但现在,通过使用 Hooks,它们可以了。

  • 第一个参数 ,todos是您要为状态命名的内容。
  • 第二个参数setTodos是您将用于设置状态的参数。

的钩子useState是 React 用来钩住组件的状态或生命周期的东西。然后您将创建一个对象数组,您将拥有状态的开始。

您将需要创建一个组件,稍后可以return在主App组件中使用组件。您将调用它Todo,它会传入todo并显示text待办事项 ( todo.text)部分

重新访问App.js并在Todo组件之前添加新App组件:

源代码/App.js
import React from 'react';
import logo from './logo.svg';
import './App.css';

function Todo({ todo }) {
  return (
    <div className="todo">
      {todo.text}
    </div>
  );
};

function App() {
  // ...
}

export default App;

让我们创建一个项目列表。

重新访问App.jsreturn用这些新代码行替换 的内容

源代码/App.js
function App() {
  // ...

  return (
    <div className="app">
      <div className="todo-list">
        {todos.map((todo, index) => (
          <Todo
            key={index}
            index={index}
            todo={todo}
          />
        ))}
      </div>
    </div>
  );
}

通过使用JavaScript 方法 ,map()您将能够通过映射todostate 中项目并按索引显示它们来创建一个新的项目数组

这添加了一个<div>for app、一个<div>fortodo-list和一个todostoTodo组件的映射

此时,也可以删除 ,logo.svg因为它将不再使用。

src/App.js到目前为止,整个文件将类似于:

源代码/App.js
import React from "react";
import "./App.css";

function Todo({ todo }) {
  return (
    <div className="todo">
      {todo.text}
    </div>
  );
};

function App() {
  const [todos, setTodos] = React.useState([
    { text: "Learn about React" },
    { text: "Meet friend for lunch" },
    { text: "Build really cool todo app" }
  ]);

  return (
    <div className="app">
      <div className="todo-list">
        {todos.map((todo, index) => (
          <Todo
            key={index}
            index={index}
            todo={todo}
          />
        ))}
      </div>
    </div>
  );
}

export default App;

在 Web 浏览器中打开您的应用程序。将显示三个待办事项:

待办事项应用程序视图

您现在正在阅读数据,可以继续了解 CRUD 的其他方面。

第 4 步 – 创建待办事项

现在,让我们让您的应用程序能够为您的待办事项应用程序创建一个新项目。

App.js文件中,您需要添加一些内容。

首先,您将添加另一个名为TodoForm. 在此组件中,您希望:

  • 从输入字段的空状态开始。
  • 能够通过设置状态来更新表单。
  • 处理提交。

要设置你的状态,你可以这样写:

const [value, setValue] = React.useState("");

第一个是“值”,第二个是您将如何设置状态。状态开始时为空,当您向状态添加内容时,它会将其添加到您的待办事项列表中。

您将需要添加一个handleSubmit可以处理您的addTodo函数并将项目添加到列表中的变量如果输入框中没有任何内容并且用户按下ENTER,则您希望它不会将空项目添加到列表中。

将功能添加到具有输入框的表单中:

源代码/App.js
// ...

function TodoForm({ addTodo }) {
  const [value, setValue] = React.useState("");

  const handleSubmit = e => {
    e.preventDefault();
    if (!value) return;
    addTodo(value);
    setValue("");
  };

  return (
    <form onSubmit={handleSubmit}>
      <input
        type="text"
        className="input"
        value={value}
        onChange={e => setValue(e.target.value)}
      />
    </form>
  );
}

function App() {
  // ...
}

// ...

将此新TodoForm组件添加到您的App组件中:

源代码/App.js
function App() {
  // ...

  return (
    <div className="app">
      <div className="todo-list">
        {todos.map((todo, index) => (
          <Todo
            key={index}
            index={index}
            todo={todo}
          />
        ))}
        <TodoForm addTodo={addTodo} />
      </div>
    </div>
  );
}

addTodo现在让我们构建函数。

组件App.js状态下App,该函数将能够获取现有项目列表,添加新项目,并显示该新列表。

源代码/App.js
function App() {
  // ...

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

  return(
    // ...
  );
}

请注意,没有this.state. 使用新的 React Hooks,您将毫无用处,this.state因为新的 Hooks 知道它将在某些地方隐含。

代码中还有一个扩展运算符todos为您复制列表之前的三个点,以便您能够添加新的待办事项。然后使用您之前设置的关键字,您将使用setTodos.

在 Web 浏览器中打开您的应用程序。应该显示三个待办事项。还应该有一个字段用于添加新的待办事项:

在待办事项应用中创建函数

您现在正在创建数据并可以继续处理 CRUD 的其他方面。

步骤 5 — 更新待办事项

让我们添加功能,以便在您的待办事项列表中完成一项时划掉它们。

您的App组件中的状态需要一些额外的东西才能使“已完成”状态能够改变。您将在对象列表中添加另一个键值对。

通过添加一个isCompleted: false值,您会将其设置false为开头,并在出现提示时将其更改为true

重新访问App.js并添加isCompleted到您的状态:

源代码/App.js
function App() {
  const [todos, setTodos] = React.useState([
    {
      text: "Learn about React",
      isCompleted: false
    },
    {
      text: "Meet friend for lunch",
      isCompleted: false
    },
    {
      text: "Build really cool todo app",
      isCompleted: false
    }
  ]);

  // ...
}

您将需要一个类似addTodo函数的函数,但是这个函数可以将一个项目标记为“完成”。您将执行在 中所做的类似操作addTodo,例如使用展开运算符来获取当前项目列表。在此函数中,您将isCompleted状态更改为true以便它知道它已完成。然后它将更新状态并将状态设置为newTodos.

使用以下内容更新您的代码:

源代码/App.js
function App() {
  // ...

  const completeTodo = index => {
    const newTodos = [...todos];
    newTodos[index].isCompleted = true;
    setTodos(newTodos);
  };

  return (
    // ...
  )
}

通过completeTodoTodo函数中使用,您可以使用该功能。单击完成”按钮后,它将添加textDecoration: line-through样式并划掉项目。

您将使用三元运算符来完成一个项目并更新列表:

源代码/App.js
function Todo({ todo, index, completeTodo }) {
  return (
    <div
      className="todo"
      style={{ textDecoration: todo.isCompleted ? "line-through" : "" }}
    >
      {todo.text}
      <div>
        <button onClick={() => completeTodo(index)}>Complete</button>
      </div>
    </div>
  );
}

添加completeTodoTodo返回的部分App组成:

源代码/App.js
function App() {
  // ...

  return (
    <div className="app">
      <div className="todo-list">
        {todos.map((todo, index) => (
          <Todo
            key={index}
            index={index}
            todo={todo}
            completeTodo={completeTodo}
          />
        ))}
        <TodoForm addTodo={addTodo} />
      </div>
    </div>
  );
}

在 Web 浏览器中打开您的应用程序。将显示三个待办事项。还将有一个完成按钮,用于将待办事项标记为已完成。

项目更新为完成状态的待办事项应用

您现在正在更新数据,可以继续进行 CRUD 的最后一个方面。

步骤 6 — 删除待办事项

让我们添加删除待办事项列表中的项目的功能。

您将构建removeTodo函数,以便当您单击X删除项目时,该项目将被删除。该功能将被其他App组件定位组件状态下

源代码/App.js
function App() {
  // ...

  const removeTodo = index => {
    const newTodos = [...todos];
    newTodos.splice(index, 1);
    setTodos(newTodos);
  };

  return (
    // ...
  )
}

在此removeTodo函数中,您将再次使用扩展运算符,但是一旦您获取当前列表,您将拼接项目数组中的所选索引。删除后,您将通过将其设置setTodos为 来返回新状态newTodos

在您的Todo函数中,您需要添加一个按钮来删除待办事项:

源代码/App.js
function Todo({ todo, index, completeTodo, removeTodo }) {
  return (
    <div
      className="todo"
      style={{ textDecoration: todo.isCompleted ? "line-through" : "" }}
    >
      {todo.text}
      <div>
        <button onClick={() => completeTodo(index)}>Complete</button>
        <button onClick={() => removeTodo(index)}>x</button>
      </div>
    </div>
  );
}

添加removeTodoTodo返回的部分App组成:

源代码/App.js
function App() {
  // ...

  return (
    <div className="app">
      <div className="todo-list">
        {todos.map((todo, index) => (
          <Todo
            key={index}
            index={index}
            todo={todo}
            completeTodo={completeTodo}
            removeTodo={removeTodo}
          />
        ))}
        <TodoForm addTodo={addTodo} />
      </div>
    </div>
  );
}

在 Web 浏览器中打开您的应用程序。将显示三个待办事项。还将有一个用于删除待办事项X按钮。

带有删除按钮的待办事项应用

您现在正在删除数据并实现了 CRUD 的所有四个方面。

第 7 步 – 完成应用程序

Todo组件、TodoForm组件和App组件放在一起后,您的App.js文件将类似于:

源代码/App.js
import React from "react";
import "./App.css";

function Todo({ todo, index, completeTodo, removeTodo }) {
  return (
    <div
      className="todo"
      style={{ textDecoration: todo.isCompleted ? "line-through" : "" }}
    >
      {todo.text}
      <div>
        <button onClick={() => completeTodo(index)}>Complete</button>
        <button onClick={() => removeTodo(index)}>x</button>
      </div>
    </div>
  );
}

function TodoForm({ addTodo }) {
  const [value, setValue] = React.useState("");

  const handleSubmit = e => {
    e.preventDefault();
    if (!value) return;
    addTodo(value);
    setValue("");
  };

  return (
    <form onSubmit={handleSubmit}>
      <input
        type="text"
        className="input"
        value={value}
        onChange={e => setValue(e.target.value)}
      />
    </form>
  );
}

function App() {
  const [todos, setTodos] = React.useState([
    {
      text: "Learn about React",
      isCompleted: false
    },
    {
      text: "Meet friend for lunch",
      isCompleted: false
    },
    {
      text: "Build really cool todo app",
      isCompleted: false
    }
  ]);

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

  const completeTodo = index => {
    const newTodos = [...todos];
    newTodos[index].isCompleted = true;
    setTodos(newTodos);
  };

  const removeTodo = index => {
    const newTodos = [...todos];
    newTodos.splice(index, 1);
    setTodos(newTodos);
  };

  return (
    <div className="app">
      <div className="todo-list">
        {todos.map((todo, index) => (
          <Todo
            key={index}
            index={index}
            todo={todo}
            completeTodo={completeTodo}
            removeTodo={removeTodo}
          />
        ))}
        <TodoForm addTodo={addTodo} />
      </div>
    </div>
  );
}

export default App;

您现在拥有了 CRUD 所有四个方面的应用程序。创建待办事项、阅读待办事项、更新待办事项和删除待办事项。

结论

当涉及到 Web 开发中的 CRUD 时,待办事项应用程序可以是一个很好的提醒或起点。能够读取信息、创建新信息、更新现有信息和删除信息在任何应用程序中都非常强大。

在本教程中,您使用React Hooks创建了一个 CRUD 待办事项列表应用程序,它允许代码清晰、简洁和直接。

如果您想了解有关 React 的更多信息,请查看我们的 React 主题页面以获取练习和编程项目。

觉得文章有用?

点个广告表达一下你的爱意吧 !😁