首页 > 解决方案 > todos.map 不是函数 - 无法编辑特定项目

问题描述

我正在尝试使用带有编辑选项的待办事项应用程序。目标是单击编辑按钮,这将打开一个输入字段,键入新的编辑文本,然后有两个选择,是否保存更改。

我已经设法为其编写代码以打开输入字段,并且能够单击按钮以不保存更改,但发生的情况是它打开了所有待办事项的输入字段,并且每当我尝试要更新特定 todo 的值,我收到错误“todos.map 不是函数”。

这是 TodoList.js

import Todo from "./Todo";
import AddTodo from "./AddTodo";
import { v4 as uuidv4 } from "uuid";

const TodoList = () => {
  //Handlers Add/Remove/RemoveAll/Edit
  const addTodoHandler = (input) => {
    setTodos([
      ...todos,
      {
        name: input,
        id: uuidv4(),
      },
    ]);
  };

  const changeEditMode = (id) => {
    setEditMode(!editMode);
    console.log(id);
  };

  const removeTodosHandler = () => {
    if (window.confirm("Are you sure you want to delete everything?")) {
      setTodos([]);
    }
  };

  const removeTodoHandler = (id) => {
    setTodos(todos.filter((todo) => todo.id !== id));
  };

  const updateValue = (id) => {
    inputRef.current.focus();
    setEditMode(!editMode);
    setTodos({ name: inputRef.current.value });
  };

  //Todo list states.
  const inputRef = useRef("");
  const [todos, setTodos] = useState([]);
  const [editMode, setEditMode] = useState(false);

  return (
    <div>
      <div>
        {todos.map((todo) => {
          return (
            <div>
              {editMode ? (
                <div>
                  {" "}
                  <input
                    type="text"
                    defaultValue={todo.name}
                    ref={inputRef}
                  ></input>
                  <button onClick={(e) => updateValue(todo.id)}>ok</button>
                  <button onClick={(e) => setEditMode(!editMode)}>x</button>
                </div>
              ) : (
                <div></div>
              )}
              <Todo name={todo.name} key={todo.id} />
              <button onClick={() => removeTodoHandler(todo.id)}>X</button>
              <button onClick={(e) => changeEditMode(todo.id)}>Edit</button>
            </div>
          );
        })}
      </div>
      <AddTodo
        handleAddTodo={addTodoHandler}
        removeTodosHandler={removeTodosHandler}
        revemoveTodoHandler={removeTodoHandler}
      />
    </div>
  );
};

export default TodoList;

这是 Todo.js


const Todo = ({ name }) => {
  return (
    <div>
      <div>{name}</div>
    </div>
  );
};

export default Todo;

任何帮助表示赞赏!

标签: javascriptreactjs

解决方案


在您的updateValue方法中,您将 todoList 设置为对象。

  const updateValue = (id) => {
    inputRef.current.focus();
    setEditMode(!editMode);
    setTodos({ name: inputRef.current.value });
  };

但是你要做的是首先找出带有 id 的项目,然后更新该 name对象的属性,然后再次将新数组设置为setTodossetter。

像这样:

    const clonedTodos = todos;
    const todoIndex = clonedTodos.findIndex((todo) => todo.id === id);
    const updatedTodo = {
      ...clonedTodos[todoIndex],
      name: inputRef.current.value,
    };
    const updatedTodos = [...clonedTodos];
    updatedTodos[todoIndex] = updatedTodo;
    setTodos(updatedTodos);

推荐阅读