繁体   English   中英

如何使用钩子在我的 React 应用程序中编辑待办事项?

[英]How can I edit a todo in my react app using hooks?

我试图弄清楚如何使用钩子在我的 React 应用程序中编辑待办事项,但我似乎无法弄清楚如何编写代码。

我在网上看到的大多数解决方案都使用类组件,并且它的编写逻辑与我的应用程序不同。

这是我当前的代码

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

        const addTodo = todo => {
          if (!todo.text || /^\s*$/.test(todo.text)) {
            return;
          }

          const newTodos = [todo, ...todos];

          setTodos(newTodos);
          console.log(newTodos);
        };

        const removeTodo = id => {
          const removedArr = [...todos].filter(todoId => todoId.id !== id);

          setTodos(removedArr);
        };

        const completeTodo = id => {
          let updatedTodos = todos.map(todo => {
            if (todo.id === id) {
              todo.isComplete = !todo.isComplete;
            }
            return todo;
          });
          setTodos(updatedTodos);
        };

        const editTodo = e => {
          setTodos(e.target.value);
        };

        return (
          <>
            <TodoForm onSubmit={addTodo} />
            {todos.map(todo => (
              <div>
                <div
                  key={todo.id}
                  className={todo.isComplete ? 'complete' : ''}
                  key={todo.id}
                  onClick={() => completeTodo(todo.id)}
                >
                  {todo.text}
                </div>
                <FaWindowClose onClick={() => removeTodo(todo.id)} />
              </div>
            ))}
          </>
        );
      }

这是另一个组件的代码

        function TodoForm(props) {
          const [input, setInput] = useState('');

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

          const handleSubmit = e => {
            e.preventDefault();

            props.onSubmit({
              id: Math.floor(Math.random() * 10000),
              text: input,
              complete: false
            });
            setInput('');
          };

          return (
            <form onSubmit={handleSubmit}>
              <input
                placeholder='todo...'
                value={input}
                onChange={handleChange}
                name='text'
              />
              <button onClick={handleSubmit}>add todo</button>
            </form>
          );
        }

所以现在一切正常,我可以添加待办事项和删除待办事项+划掉待办事项。 唯一缺少的是能够编辑它们。

我看到了一些关于使用输入表单更新文本值的建议,但我不太确定如何在我的 editTodo 函数中实现它。

与您的 removeTodo 处理程序类似,您希望将 todo.id 传递给 completeTodo。

<div className={todo.isComplete ? "complete" : ""} key={todo.id} onClick={() => completeTodo(todo.id)}>

然后您将更新 todo 对象中的 bool 值。

const completeTodo = (id) => {
   let updatedTodos = todos.map(todo => {
        if(todo.id === id){
            todo.isComplete = true
         }
       return todo
  }) 
    setTodos(updatedTodos)
};

编辑:添加样式删除线然后您将有条件地添加基于 isComplete 布尔值的 css 样式

CSS

.complete {
    text-decoration: line-through;
}

为了能够单击“删除”按钮,请将其放在地图功能中的待办事项 div 之外。

{todos.map((todo, isComplete) => (
          <>
              <div
                key={todo.id}
                onClick={completeTodo}
                className={isComplete ? 'complete' : ''}
              >
                {todo.text}
                
              </div>
             <FaWindowClose onClick={() => removeTodo(todo.id)} />
         </>
 ))}

在另一个问题中与您讨论时,它是:

TodoList.js

import React, { useState } from "react";
import TodoForm from "./TodoForm";
import Todo from "./Todo";

function TodoList({ onClick }) {
  const [todos, setTodos] = useState([]);
  //Track is edit clicked or not
  const [editId, setEdit] = useState(false);
  //Save input value in input box
  const [inputValue, setInputValue] = useState("");

  const handleEditChange = (id, text) => {
    setEdit(id);
    setInputValue(text);
  };
  const addTodo = (todo) => {
    if (!todo.text || /^\s*$/.test(todo.text)) {
      return;
    }

    const newTodos = [todo, ...todos];

    setTodos(newTodos);
    console.log(newTodos);
  };

  const removeTodo = (id) => {
    const removedArr = [...todos].filter((todoId) => todoId.id !== id);

    setTodos(removedArr);
  };

  const completeTodo = (id) => {
    let updatedTodos = todos.map((todo) => {
      if (todo.id === id) {
        todo.isComplete = !todo.isComplete;
      }
      return todo;
    });
    setTodos(updatedTodos);
  };

  const editTodo = (id, text) => {
    let editTodos = todos.map((todo) => {
      if (todo.id === id) {
        todo.text = text;
      }
      return todo;
    });
    setTodos(editTodos);
    setEdit(false);
  };

  return (
    <>
      <TodoForm onSubmit={addTodo} />
      {/* I want to move this code below into a new component called Todo.js */}
      <Todo
        todos={todos}
        completeTodo={completeTodo}
        removeTodo={removeTodo}
        editTodo={editTodo}
        handleEditChange={handleEditChange}
        editId={editId}
        inputValue={inputValue}
        setInputValue={setInputValue}
      />
    </>
  );
}

export default TodoList;



待办事项.js

// I want to move this code into this component
import React, { useState } from "react";

import { FaWindowClose, FaRegEdit } from "react-icons/fa";

const Todo = ({
  todos,
  completeTodo,
  removeTodo,
  editTodo,
  editId,
  handleEditChange,
  inputValue,
  setInputValue
}) => {
  return todos.map((todo) => (
    <div className="todo-row">
      {editId === todo.id ? (
        <input
          type="text"
          value={inputValue}
          onChange={(e) => setInputValue(e.target.value)}
        />
      ) : (
        <div
          key={todo.id}
          className={todo.isComplete ? "complete" : ""}
          onClick={() => completeTodo(todo.id)}
        >
          {todo.text}
        </div>
      )}
      {editId === todo.id ? (
        <button onClick={() => editTodo(todo.id, inputValue)}>Edit todo</button>
      ) : (
        <>
          <FaWindowClose onClick={() => removeTodo(todo.id)} />
          <FaRegEdit onClick={() => handleEditChange(todo.id, todo.text)} />
        </>
      )}
    </div>
  ));
};

export default Todo;

确保您首先阅读并理解代码。 您在completeTodo 中所做的事情的逻辑非常简单。 您只需要更新文本部分。 棘手的部分是在输入中打开。 因此,如果用户单击 id 设置该 id,逻辑就像跟踪。 并检查 id 是否存在具有该 id 值的打开输入,否则正常。

这是这个 POC 的演示: https : //codesandbox.io/s/nostalgic-silence-idm21? file =/ src/Todo.js: 0-1059

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM