Реагировать на ловушку useState не обновляется с помощью onSubmit - PullRequest
1 голос
/ 25 апреля 2019

В настоящее время у меня возникла проблема с переводом значения поля ввода в состояние onSubmit.

codesandbox

Я пытаюсь установить значение поля ввода в состояние, чтобы я мог использовать это значение после обновления компонента для перенаправления пользователя на другую страницу. Я проверил путь вручную, и он работает, но поскольку состояние не обновляется синхронно, перенаправление не работает. Я могу отобразить входное значение на странице, но если я попытаюсь зарегистрировать его, оно долго не определено (в первый раз) и предыдущее состояние при второй передаче.

import React, { useRef, useState } from "react";
import { db } from "../firebase";
import { Redirect } from "@reach/router";

function CreateProject(props) {
  const [id, setID] = useState(null);
  const colorRef = useRef(null);
  const projectNameRef = useRef(null);

  const handleSubmit = e => {
    e.preventDefault();
    const project = {
      name: projectNameRef.current.value,
      colors: [colorRef.current.value],
      colorName: colorNameRef.current.value,
      createdAt: new Date()
    };
    setID(projectNameRef.current.value);

    db.collection("users")
      .doc(`${props.user}`)
      .collection("projects")
      .doc(`${projectNameRef.current.value}`)
      .set({ ...project });
    e.target.reset();
  };


  return id ? (
    <Redirect from="/projects/new" to={`projects/:${id}`} noThrow />
  ) : (
    <div>
      <div>
        <h1>Create new selection</h1>
        <form onSubmit={handleSubmit}>
          <label>Color</label>
          <input ref={colorNameRef} type="text" name="colorName" />
          <label>Project Name</label>
          <input ref={projectNameRef} type="text" name="projectName" required />
          <button type="submit">Submit</button>
        </form>
      </div>
    </div>
  );
}

export default CreateProject;

Реакция: 16,8.6

Ответы [ 2 ]

1 голос
/ 25 апреля 2019

Это способ, которым реагируют ловушки useState работает, чтобы сделать что-то после изменения состояния, вы должны выполнить это внутри useEffect ловушка, как показано ниже:

useEffect(() => {
  if (id) {
    console.log(id);
    projectNameRef.current.value = ''
  }
}, [id])

Этот эффект будет запускаться каждый раз, когда изменяется значение id (и при первом рендеринге), чтобы вы могли добавить туда свою логику и выполнить желаемые действия на основе изменения состояния.

0 голосов
/ 25 апреля 2019

Я думаю, что использование вами ref здесь неуместно и может быть причиной проблемы. Я бы переписал вашу функцию следующим образом.

function CreateProject() {
  const [id, setID] = useState(null);
  const [shouldRedirect, setShouldRedirect] = useState(false);

  const handleSubmit = e => {
    e.preventDefault();
    setShouldRedirect(true);
  };

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

  return shouldRedirect ? (
    <Redirect from="/projects/new" to={`projects/:${id}`} noThrow />
  ) : (
    <div>
      <div>
        <h1>Create new selection</h1>
        <form onSubmit={handleSubmit}>
          <label>Project Name</label>
          <input onChange={handleChange} type="text" name="projectName" required />
          <button type="submit">Submit</button>
        </form>
      </div>
    </div>
  );

Таким образом, ваше состояние всегда обновляется и, следовательно, ваш URL-адрес перенаправления. Когда вы отправляете, вы просто указываете компоненту, который должен быть отправлен, с текущим идентификатором.

Вы можете увидеть, как это работает, из документации React.

Вы даже можете заменить условный рендер функциональным вызовом на history.push, используя withRouter. См. Совет по этому вопросу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...