0

I'm having a strange issue with state in my React app. In this I use one state and one useEffect. State is used to store posts which is fetch from jsonplaceholder. fetch and set state written inside the useffect with empty array as an option for dependency.

I even retrieve the data from jsonplaceholder, it not set the usestate. it display empty array which is the initial value.

sometimes it update when I save the code but after I refresh the page it will gone and not updating again I even tried many times

but the problem is react-dev-tools shows state updated value which is all the posts. but 'console.log() ' doesn't show the data.

tell why the setposts() method doesn't seem to be setting the state,

import React,{ useEffect,useState} from 'react'

export default function Test() {

    const [ posts, setposts] = useState([]);

    useEffect(()=>{

        fetch('https://jsonplaceholder.typicode.com/posts',{

            method:'get',
    
        }).then(result=>{
            return result.json();
        }).then((data)=>{
            console.log(data);
            setposts(data);
        
            console.log(posts);
        })

    },[])

    return (
        <div>

               
        </div>
    )
}
Jason Aller
  • 3,541
  • 28
  • 38
  • 38
Yasith
  • 19
  • 4

3 Answers3

0

The useState API don't have a callback like setState have in React classes. All you can do to wait for the state update to finish is, to use a useEffect hook,like this

useEffect(()=>{

        fetch('https://jsonplaceholder.typicode.com/posts',{

            method:'get',
    
        }).then(result=>{
            return result.json();
        }).then((data)=>{
            console.log(data);
            setposts(data);
        
            console.log(posts);
        })

    },[data])
DevLoverUmar
  • 11,809
  • 11
  • 68
  • 98
  • I guess this is wrong, because you are watching for changes in data to make the api call... using useEffect without passing data to be watched will run this only at once when component is mounted – Diego Vinícius Nov 08 '20 at 04:11
  • @DiegoVinícius It runs **both** on mount (no "data") **and** when data is changing, so this code should be OK. Not? Thx. – user2078023 Mar 25 '22 at 10:34
0

Basically, react does not change the state immediately, see useState set method not reflecting change immediately

If you want to see that the state is really changed, try to render posts, like (poor example, I know):

...
return (
        <div>{JSON.stringify(posts)}</div>
    )
0

Your code is right but the state isnt placed right away, so by the time you calling console log the value is not ready yet, but that wont be a issue if you show that data in the html

Made some changes and little organize in your code

export default Test = {
  const [ posts, setposts] = useState([]);

  useEffect(()=>{
      fetch('https://jsonplaceholder.typicode.com/posts')
      .then(result => result.json())
      .then((data)=>{
        console.log(data); // Will be written because you are already at the end of the promisse
        setposts(data);      
        console.log(posts); // Will be empty cuz the async load of state
      });
  },[])

  return (
    <>          
      {posts.map(post => (
        <ul>
          <li key="{post.id}">{post.title}</li>
        </ul>
      ))}    
    </>
  )
}
Diego Vinícius
  • 2,125
  • 1
  • 12
  • 23