This is because setState
calls are asynchronous. Read it here and here. As the per the doc I linked
- setState() enqueues changes to the component state and tells React that this component and its children need to be re-rendered with the updated state
- setState() does not always immediately update the component. It may batch or defer the update until later. This makes reading this.state right after calling setState() a potential pitfall
Therefore, the state is usually not updated yet when you console.log
it on the next line, but you can access/see the updated state on the next render. If you want to log values, you can put them as inside a <pre>
tag in your HTML, or do console.log
at the beginning, like below:
const [firstPost, setFirstPost] = useState();
// Console.log right on at the start of the render cycle
console.log("First post", firstPost);
useEffect(() => {
(async () => {
await onFetchPosts();
})();
}, []);
const onFetchPosts = async () => {
try {
const { body } = await publicService.fetchPostById(119);
// get post
const post = body.posts;
if (post && post.postsId) {
console.log(`save...`, body.posts);
setFirstPost(body.posts);
}
// Do not console.log the state here
// console.log(`firstPost...`, firstPost);
} catch (error) {
console.log(error);
} finally {
setLoading(false);
}
};
// Can also debug like this
return <pre>{JSON.stringify(firstPost)}</pre>;