I have the following code snippet, and I expected it to result in an infinite loop due to a state update inside a fetch callback inside the body of the component without using 'useEffect'. However, it's not behaving as expected. Here's the code:
function App() {
const [cartContent, setCartContent] = useState(null);
fetch("https://fakestoreapi.com/carts/6")
.then((resp) => resp.json())
.then((data) => {
setCartContent("test");
});
console.log(cartContent);
return <div className="cartContent">{cartContent}</div>;
}
export default App;
My understanding was that console.log(cartContent) should log the initial value of cartContent, then when setCartContent("test") is called inside the fetch callback, it should log "test", and this process should repeat indefinitely, creating an infinite loop.
Could someone please help me understand why this code doesn't result in an infinite loop as expected? Any insights or explanations would be greatly appreciated. Thank you!
Your expectation is a bit misguided. The code you have shared always updates the cartContent
state to the string literal "test"
, but strings are kind of like primitives in that they are always equal to themselves, even when the variables holding those strings are different references. After the second enqueued state update is processed React see's the same state value and doesn't trigger any additional rerender.
See Bailing out of a State update:
If you update a State Hook to the same value as the current state, React will bail out without rendering the children or firing effects. (React uses the
Object.is
comparison algorithm.)Note that React may still need to render that specific component again before bailing out. That shouldn’t be a concern because React won’t unnecessarily go “deeper” into the tree.