简体   繁体   中英

setState hook not updating after fetch with HTTP PUT

So I'm trying out basic todo app with edit and delete feature. I'm having problems with my edit feature. I have two main components in my app namely InputTodo for adding todo items and ListTodo which contains two additional subcomponents (TodoItem for each todo and EditTodo which shows an editor for a selected todo). Whenever the Edit Button inside a certain TodoItem is clicked, the EditTodo component is showed. When the Confirm button in EditTodo component is clicked, a PUT request will be sent to update the database (PostgreSQL in this case) through Node. After successfully sending this send request, I would like to re-render the list of TodoItem components. I'm doing this by fetching the updated list of values from the database through a different GET request then calling setState given the response from the GET request. However, the GET request's response doesn't reflect the PUT request done earlier. Thus, the app still renders the un-updated list of todos from the database.

Here are some code snippets

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>
  );
};

I guess that the problem is - In editTodo function, you are calling getTodos() function. But, you are not updating the state with the response you get. See if this helps.

  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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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