So here’s the code I’m confused about:
import React from "react"
export default function App() {
const [starWarsData, setStarWarsData] = React.useState({})
console.log(starWarsData)
React.useEffect(function() {
fetch("https://swapi.dev/api/people/1")
.then(res => res.json())
.then(data => setStarWarsData(data))
}, [starWarsData])
return (
<div>
<pre>{JSON.stringify(starWarsData, null, 2)}</pre>
</div>
)
}
This code will constantly be re-rendering the component in an infinite loop, but I dont understand why that is. In the useEffect function, it uses a fetch request for some data about Star Wars and will execute setStarWarsData on that data.
My understanding of this code is that when it first renders the component, it will then call the useEffect function (as always). The useEffect function will then change the state of the variable starWarsData which will then re-render the whole component however according to my flawed logic, the useEffect function shouldnt be executed after this current render of the component as the variable starWarsData is the same between the previous render and this render. If you put a console.log(starWarsData), the starWarsData variable will have the same value between the previous render of the component and the current render of the component, that is both will be objects that have the same content inside the objects.
Why is this logic wrong? Any help is appreciated 🙂
>Solution :
The useEffect has two parameters, the first parameter is the function you want it to call.
The second parameter is an array to watch and call your function whenever it change (in addition to when the component is mounted first).
Your passing the state starWarsData in the array and inside of your function setting this state, the state change triggers useEffect to call your function again, creating an infinite loop!
Pass an empty array if you want the function to get called only on component mount.
React.useEffect(function() {
fetch("https://swapi.dev/api/people/1")
.then(res => res.json())
.then(data => setStarWarsData(data))
}, [])