Использование перехватчиков React для запуска событий с побочными эффектами, такими как onClick (), вызывающим fetch () - PullRequest
1 голос
/ 13 января 2020

Я использую React с перехватчиками, используя useState() для внутреннего состояния и useEffect() для внешних побочных эффектов, таких как вызов веб-службы, как описано в документации React.

В этом примере я имею кнопка, и нажатие на кнопку должно вызвать веб-сервис. Это работает с useEffect() в первый раз при инициализации, но дальнейшие нажатия кнопок не вызовут веб-сервис.

Теперь мое хакерское решение состоит в том, чтобы ввести дополнительное состояние, называемое hackIndex, которое увеличивается каждый раз, когда кнопка щелкнул, но это не выглядит особенно элегантно:

import React, { useState, useEffect } from "react";

function App() {
  const [answers, setAnswers] = useState([]);
  // very ugly hack
  const [hackIndex, setHackIndex] = useState(0);
  // when hackIndex changes, gets data from web service and adds it to answers array
  // also called when the page is initialized, but we can ignore that for this question
  useEffect(() => {
    fetch("https://jsonplaceholder.typicode.com/todos/1")
      .then(response => response.json())
      .then(json => setAnswers([...answers, json.title]));
  }, [hackIndex]);
  // returning React JSX
  return (
    <div>
      <div>
        <button
          onClick={e => {
            setHackIndex(hackIndex + 1);
          }}
        >
          Call web service
        </button>
      </div>
      <div>Collected answers:</div>
      {answers.map(answer => (
        <div>{answer}</div>
      ))}
    </div>
  );
}

export default App;

Я еще не использовал редукторы, так как из Java и Angular они кажутся мне немного странными. Но useReducer() должен использовать только чистые функции, поэтому они, похоже, не подходят.

Это несколько базовая c функциональность, но я не нахожу статей об этой проблеме или кто-либо, кто ее спрашивает. Или я что-то упускаю полностью.

Есть похожий вопрос, но он касается Apollo для запросов GraphQL, использующих useQuery(), тогда как я использую простой вызов Vanilla JS fetch(): Как запустить React Hooks после события

1 Ответ

1 голос
/ 13 января 2020

setX функции, возвращаемые из useState, имеют возможность функциональное обновление , которая принимает функцию в качестве аргумента и вызывает эту функцию с предыдущим значением состояния. Это позволяет вашему fetchAnswers не нуждаться в доступе к предыдущему значению answers.

import React, { useState, useEffect } from "react";

function App() {
  const [answers, setAnswers] = useState([]);

  function fetchAnswers() {
    fetch("https://jsonplaceholder.typicode.com/todos/1")
      .then(response => response.json())
      .then(json => setAnswers(prevAnswers => [...prevAnswers, json.title]));
  }

  useEffect(() => {
    fetchAnswers();
  }, []);

  // returning React JSX
  return (
    <div>
      <div>
        <button
          onClick={fetchAnswers}
        >
          Call web service
        </button>
      </div>
      <div>Collected answers:</div>
      {answers.map(answer => (
        <div>{answer}</div>
      ))}
    </div>
  );
}

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