使用HTTP PUT获取后setState挂钩未更新

时间:2020-05-30 01:59:44

标签: javascript reactjs react-hooks

因此,我正在尝试具有编辑和删除功能的基本待办事项应用程序。我的编辑功能有问题。我的应用程序中有两个主要组件,即用于添加待办事项的InputTodo和包含两个附加子组件的ListTodo(每个待办事项的TodoItem和显示所选待办事项的编辑器的EditTodo)。只要单击某个TodoItem中的“编辑”按钮,就会显示EditTodo组件。单击EditTodo组件中的Confirm按钮时,将通过Node发送一个PUT请求以更新数据库(在这种情况下为PostgreSQL)。成功发送此发送请求后,我想重新呈现TodoItem组件列表。我这样做是通过一个不同的GET请求从数据库中获取值的更新列表,然后在给定GET请求响应的情况下调用setState。但是,GET请求的响应不能反映之前完成的PUT请求。因此,该应用仍会从数据库中呈现待办事项的未更新列表。

以下是一些代码段

const ListTodo = (props) => {
  const [todos, setTodos] = useState([]);
  const [editorOpen, setEditorOpen] = useState(false);
  const [selectedId, setSelectedId] = useState();

  const getTodos = async () => {
    console.log('getTodos() called');
    try {
      const response = await fetch("http://localhost:5000/todos");
      const jsonData = await response.json();
      setTodos(jsonData);
      console.log(todos);
    } catch (err) {
      console.error(err.message);
    }
    console.log('getTodos() finished');
  };
const editTodo = async description_string => {
    console.log('editTodo() called');
    try {
      const body = { description: description_string };
      const response = await fetch(
        `http://localhost:5000/todos/${selectedId}`,
        {
          method: "PUT",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify(body)
        }
      );
      console.log(response);
      await getTodos();
      props.handleListModified();
    } catch (err) {
      console.error(err.message);
    }
    console.log('editTodo() finised');
  }

  const handleItemButtonClick = (button, row_key) => {
    if (button === 'delete') {
      deleteTodo(row_key);
      setEditorOpen(false);
    } else if (button === 'edit') {
      setEditorOpen(true);
      setSelectedId(row_key);
      console.log(todos.filter(todo => { return todo.todo_id === row_key})[0].description);
    }
  };
  const handleEditorButtonClick = async (button, description_string) => {
    if (button === 'cancel') {
      setSelectedId(null);
    } else if (button === 'confirm') {
      await editTodo(description_string);
    }
    setEditorOpen(false);
  };

  useEffect(() => {
    console.log('ListTodo useEffect() trigerred');
    getTodos();
  }, [props.listModified]);

  return(
    <Fragment>
      <table>
        <tbody>
          {todos.map( todo => (
            <TodoItem
              key={todo.todo_id}
              todo_id={todo.todo_id}
              description={todo.description}

              handleClick={handleItemButtonClick} />
          ))}
        </tbody>
      </table>
      { editorOpen &&
        <EditTodo
          handleEditorButtonClick={handleEditorButtonClick}

          description={todos.filter(todo => { return todo.todo_id === selectedId})[0].description}
          selectedId={selectedId} /> }
    </Fragment>
  );
};

1 个答案:

答案 0 :(得分:1)

我想问题是-在editTodo函数中,您正在调用getTodos()函数。但是,您不会使用收到的响应来更新状态。看看是否有帮助。

  const response = await fetch(
    `http://localhost:5000/todos/${selectedId}`,
    {
      method: "PUT",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(body)
    }
  );
  console.log(response);
  setTodo(await getTodos()); // Update the state with the values from fetch