setState хук не обновляется после выборки с HTTP PUT - PullRequest
0 голосов
/ 30 мая 2020

Итак, я пробую приложение basi c todo с функцией редактирования и удаления. У меня проблемы с функцией редактирования. У меня есть два основных компонента в моем приложении, а именно InputTodo для добавления элементов todo и ListTodo, который содержит два дополнительных подкомпонента (TodoItem для каждого todo и EditTodo, который показывает редактор для выбранного todo). Каждый раз, когда нажимается кнопка Edit внутри определенного TodoItem, отображается компонент EditTodo. При нажатии кнопки «Подтвердить» в компоненте EditTodo будет отправлен запрос PUT для обновления базы данных (в данном случае PostgreSQL) через Node. После успешной отправки этого запроса на отправку я хотел бы повторно отобразить список компонентов TodoItem. Я делаю это, получая обновленный список значений из базы данных с помощью другого запроса GET, а затем вызывая setState, учитывая ответ от запроса GET. Однако ответ на запрос 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 Ответ

1 голос
/ 30 мая 2020

Я предполагаю, что проблема в - В функции 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
...