Установка состояния с помощью React Hooks + Fetch API не вызывает повторную визуализацию - PullRequest
1 голос
/ 10 марта 2019

Я пытаюсь изучить React Hooks, создав простую проверку доступности домена.В частности, я играю с useState()

Цель состоит в том, чтобы просто иметь поле ввода, где пользователь вводит ключевое слово, нажимает Enter, а затем приложение запускает запрос на выборку для этого ключевого слова с номеромразличных окончаний домена.

Вот мой компонент приложения (или проверьте коды и поле здесь: https://codesandbox.io/s/5410rkrq1p)

const App = () => {
  const domainEndings = [
    ".ws",
    ".ga",
    ".cf",
    ".tk",
    ".ml",
    ".gq",
    ".kz",
    ".st",
    ".fm",
    ".je"
  ];

  const [domainString, setDomainString] = useState("");
  const [domainsArray, setDomainsArray] = useState([]);
  const [lookedUpDomainsArray, setLookedUpDomainsArray] = useState([]);

  const handleDomainChange = event => {
    setDomainString(event.target.value);
    setDomainsArray(
      domainEndings.map(ending => event.target.value.trim() + ending)
    );
  };

  let testArray = [];

  const runDomainLookup = url => {
    return fetch(
      `https://domainr.p.rapidapi.com/v2/status?domain=${url}&mashape-key=${myAPIKEY}`
    )
      .then(res => res.json())
      .then(data => {
        testArray.push({
          url: data.status[0].domain,
          status: data.status[0].status
        });
        setLookedUpDomainsArray(testArray);
      });
  };

  const handleSubmit = e => {
    e.preventDefault();
    setLookedUpDomainsArray([]);
    testArray = [];
    domainsArray.map(eachDomain => runDomainLookup(eachDomain));
  };

  return (
    <div>
      <form onSubmit={handleSubmit}>
        <input
          value={domainString}
          placeholder="type keyword then hit enter"
          onChange={e => handleDomainChange(e)}
        />
      </form>
      {lookedUpDomainsArray &&
        lookedUpDomainsArray.map((domain, index) => {
          return (
            <div key={index}>
              {domain.url} is {domain.status}
            </div>
          );
        })}
    </div>
  );
};

Ошибка, с которой я столкнулся:

  • состояние, кажется, устанавливается правильно (проверено в React Dev Tools).

  • первый ответ от сопоставленных запросов на выборку корректно отображается в DOM

  • повторная визуализация для вновь добавленного состояния (из запроса на выборку) не запускается, пока пользователь не нажмет клавишу в поле ввода

Здесьвидео, демонстрирующее это: https://streamable.com/klshu

Вы заметите, что остальные результаты не появятся, пока я не начну вводить другие символы в поле ввода

Заранее спасибо ?

1 Ответ

0 голосов
/ 10 марта 2019

Спасибо!Да, я пробовал Promise.all (), однако я хотел, чтобы каждый запрос на выборку выполнялся отдельно (например, если время ожидания одного запроса на выборку превысит ВСЕ другие).

Нашел решение для Reddit

По сути, при настройке состояния через крючки, я должен был перейти в предыдущее состояние следующим образом:

const runDomainLookup = url => {
    return fetch(
      `https://domainr.p.rapidapi.com/v2/status?domain=${url}&mashape-key=${myAPIKEY}`
    )
      .then(res => res.json())
      .then(data => {
        setLookedUpDomainsArray(prevArray => [
          ...prevArray,
          {
            url: data.status[0].domain,
            status: data.status[0].status
          }
        ]);
      });
  };

Рабочее решение на CodeSandbox: https://codesandbox.io/s/51ky3r63x

...