Понимание (множественных) операций выборки в хуке - PullRequest
0 голосов
/ 19 января 2020

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

const [state, setState] = useState({
   isLoaded: false,
   isLoaded2: false,
   response1: null,
   response2: null,
   error: null
});

useEffect(() => {
  fetch("some api", { method: "GET" })
    .then(res => res.json())
    .then(
      res => {
        setState({
          ...state,
          isLoaded: true,
          response1: res
        });
      },
      error => {
        setState({
          ...state,
          isLoaded: false,
          error: error
        });
      }
    );
  fetch("another api", {
    method: "GET"
  })
    .then(res => res.json())
    .then(
      res => {
        setState({
          ...state,
          response2: res,
          isLoaded2: true
        });
      },
      error => {
        setState({
          ...state,
          error: error
        });
      }
    );
}, []);

Состояния не обновляются, и я проверил, чтобы убедиться, что ответы API все в порядке. Эта структура работала с использованием ComponentDidMount(), поэтому мне интересно, почему она не работает в этом случае.

1 Ответ

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

Состояние обновления в функциональных компонентах по-прежнему асинхронное, попробуйте использовать синтаксис функциональное обновление , чтобы «поставить в очередь» обновления.

useEffect(() => {
  fetch("some api", { method: "GET" })
    .then(res => res.json())
    .then(
      res => {
        setState(prevState => ({
          ...prevState,
          isLoaded: true,
          response1: res
        }));
      },
      error => {
        setState(prevState => ({
          ...prevState,
          isLoaded: false,
          error: error
        }));
      }
    );
  fetch("another api", {
    method: "GET"
  })
    .then(res => res.json())
    .then(
      res => {
        setState(prevState => ({
          ...prevState,
          response2: res,
          isLoaded2: true
        }));
      },
      error => {
        setState(prevState => ({
          ...prevState,
          error: error
        }));
      }
    );
}, []);

То, что происходит, даже если есть несколько Устанавливать возникающие состояния, когда они обрабатываются, все они ссылаются на одно и то же значение состояния из предыдущего цикла рендеринга.

const [count, setCount] = useState(0);

const plus3Update = () => {
  setCount(count + 1); // count === 0
  setCount(count + 1); // count === 0
  setCount(count + 1); // count === 0
  // count === 1 now
};

const plus3FunctionalUpdate = () => {
  // using a different name to not be confused with state value
  setCount(c => c + 1); // count === 0, then 1
  setCount(c => c + 1); // count === 1, then 2
  setCount(c => c + 1); // count === 2, then 3
  // count === 3
};

Демонстрация, показывающая как обновление, так и функциональное обновление состояния обновления состояния.

Edit infallible-pond-qkdhs

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