I am new to React
and I have this simple code and I got two questions:
import { useState, useEffect } from 'react';
const UpdateArticle = () => {
let filteredArticle;
const id = 2;
const [theArticle, setTheArticle] = useState({});
const testArticles = [
{
id: 1,
title: 'Maxaan qabtaa?',
body: 'Wax daran bay ku hadlayaan kuwa halkaan ila jooga.',
writer: 'Jama',
},
{
id: 2,
title: 'Why django?',
body: 'Simple: it is very simple.',
writer: 'Dennis',
},
];
const updateArticle = () => {
filteredArticle = testArticles.find((article) => article.id === id);
setTheArticle(filteredArticle);
};
// console.log("Test");
useEffect(() => {
updateArticle();
console.log('Test');
console.log(filteredArticle);
console.log(theArticle);
}, [id]);
return (
<div className="article update">
<h1>{theArticle.title}</h1>
</div>
);
};
-
Why is the
setTheArticle
method is not setting thetheArticle
instantly? Theconsole.log
in theuseEffect
gives an empty object even though thefilteredArticle
above it has a correct value. -
the console does everything twice. This is the case even if I put one outside useEffect and outside the
updateArticle
function. for example, for the above case it gives something like this:
Test
{id: 2, title: "Why django?", body: "Simple: it is very simple.", writer: "Dennis"}
{} (empty???)
Test
{id: 2, title: "Why django?", body: "Simple: it is very simple.", writer: "Dennis"}
{} (empty???)
The question is why?
I even suspected it is my configuration and went to stackblitz. The same thing. and also I am NOT calling the component twice.
2
Answers
Answers to your questions:
setState
will not fire immediately and if you want to get the new state you should listen to it in anotheruseEffect
with this state as its dependency.useEffect
twice is because of theStrictMode
.You can read about that in the React docs.
Some advice base on your example code:
useEffect
in its dependencies array.react.dev
carefully to avoid unexpected behavior.useState is an asynchronous hook and it doesn’t change the state immediately, it has to wait for the component to re-render. useRef is a synchronous hook that updates the state immediately and persists its value through the component’s lifecycle, but it doesn’t trigger a re-render.
To use callback in the useState hook, we need to use the useEffect hook that triggers after state update and call the function after that. We need to pass state in the useEffect Dependency Array. useEffect is triggered when the state updates and then calls the inside function immediately.
you can log the state inside JSX to see actual value of the state when component has been mounted (componentDidMount)
read the following link
javascript plainenglish, useState