Установщик useState не обновляет состояние при вызове в useEffect

Примерно так, как написано в названии. Когда я console.log (репозиторий), он возвращает пустой массив. Почему состояние repos не обновляется?

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

export default () => {
  const [repos, setRepos] = useState([]);
  useEffect(() => {
    (async () => {
      try {
        let repo_lists = await axios.get(
          "https://api.github.com/users/Coddielam/repos"
          // { params: { sort: "created" } }
        );
        setRepos(repo_lists.data.slice(1).slice(-10));
        console.log(repo_lists.data.slice(1).slice(-10));
        console.log(repos);
      } catch (err) {
        setRepos([
          "Something went wrong while fetching GitHub Api./nPlease use the link below to view my git repos instead ",
        ]);
      }
    })();
  }, []);

  return (
    <div className="content">
      <h2>View my recent git repos:</h2>
      <ul>
        ...
      </ul>
    </div>
  );
};

person Eddie Lam    schedule 02.10.2020    source источник
comment
Поведение установки состояния является асинхронным по своей природе, поэтому оно не будет сразу устанавливать состояние.   -  person Subrato Patnaik    schedule 02.10.2020


Ответы (2)


Ответ очень простой. Ваш useState обновляется .. поверьте мне. Причина, по которой вы не видите его, когда console.log(), состоит в том, что SetRespos является асинхронной функцией.

Обычно, когда вы объявляете функцию для обновления вашего useState значения, react будет использовать ее как async функцию.

ПРИМЕР

const [example, setExample] = useState('');

useEffect(() => {
  
  setExample('Hello');
  console.log('I'm coming first'); // This will be executed first
  console.log(example); // This will come after this

}, [])

Результатом будет:

  I'm coming first
  // Blank Line

Но после этого ваш useState все равно обновится. Если вы хотите это увидеть, сделайте следующее:

 useEffect(() => {

  console.log(respose); // This will give you the value
}, [respos])

Я использую от useEffect до console.log() значения. В [] (массив зависимостей) мы передаем respos, что просто означает, что useEffect будет запускаться каждый раз при изменении значения respos.

Подробнее о useStates and useEffects в документации React.

person Hard Code Programmer    schedule 02.10.2020

Обновления состояния являются асинхронными. Вы увидите их отражение только на следующем рендере. Если вы консоль регистрируете состояние сразу после вызова setState, оно всегда будет записывать текущее состояние, а не будущее состояние.

Вы можете регистрировать состояние эффекта каждый раз, когда он изменяется, и вы увидите его изменение:

useEffect(() => console.log(repos), [repos]);

Этот эффект будет вызван после применения обновления состояния.

person trixn    schedule 02.10.2020