useState setter not updating state when called in useEffect

3.1k Views Asked by At

Pretty much what it says on the title. When I console.log(repos) it returns an empty array. Why is the repos state not updating?

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>
  );
};
2

There are 2 best solutions below

0
On BEST ANSWER

Answer is very simple. Your useState is updating .. believe me. The reason why you don't see it when you console.log() is because SetRespos is an asynchronous function.

Basically when you declare a function to update you useState value, react will use it as an async function

EXAMPLE

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

}, [])

The output will be :

  I'm coming first
  // Blank Line

But still your useState will update after this. If you want to see that do this :

 useEffect(() => {

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

I'm using a separate useEffect to console.log() the value. In the [] (dependency array) we pass respos which simply means that the useEffect will run every time the value of respos changes.

Read more about useStates and useEffects in react's documentation

0
On

State updates are async. You will only see them reflected on the next render. If you console log the state immediately after calling setState it will always log the current state, not the future state.

You can log the state in an effect every time it changes and you will see it changing:

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

This effect will be called after the state update has been applied.