Im currently following a react course and got stuck with this question, in this code snippet im trying to fetch repositories using github API and while data is in process I used a state isLoading
which has an initial value of false
, and inside the async
function this state will be toggled to true
and then to false
after the request is done, and im wondering why the "Loading…" text appears since react batches all updates until the end, why and how the JSX get access to the true value of the isLoading state? And thanks!
This is the component im using
function App() {
const [isLoading, setIsLoading] = useState(false);
const [repos, setRepos] = useState([]);
useEffect(() => {
async function fetchRepos() {
setIsLoading(true);
const reposFetch = await fetch("https://api.github.com/users/OthmaneNissoukin/repos");
const data = await reposFetch.json();
setIsLoading(false);
}
fetchRepos();
}, []);
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
{isLoading ? <h2>Loading...</h2> : <div>Done!</div>}
</div>
);
}
2
Answers
After some researches I found that react does run the
setStates
update functions inside a batch that runs synchronously which will handle all the changes for updating and perform only one re-render in case if the setState is being performed in a synchronous function (like an event handler).For example:
}
However, when trying to update the states inside an
async
function then the changes will be handled outside the batch which will lead to re-render for every useState update inside the async function.After some researches I found that react does run the setStates update functions inside a batch that runs synchronously which will handle all the changes for updating and perform only one re-render in case if the setState is being performed in a synchronous function (like an event handler).
for more details, I recommand checking this article: https://dev.to/adamklein/we-don-t-know-how-react-state-hook-works-1lp8
And so in my question, the reason why "Loading..." appeared when the
fetch
has started was due to theasync
function that prevented the updates from batching all changes until the end and instead caused multiple re-renders wheneverisLoading
state was changed.since you dont have the data initially you need to make the default value of is loading to be true in the first render Loading will be displayed , in the second render toggled by the useEffect you fetch the data , set the data to the result of your fetch request and then change the state of loading .
your code should look like this :
}