I have a very simple NextJS app in v13.4+ and it is running useEffect 3 times (even though it is set with an empty dependency array.)
I was hoping that it would only run 1 time (on the equivalent of componentDidMount) due to the empty array.
I’m not sure why useEffect is running three times. I put a getData call in the useEffect and I prefer this not to run three times when the user goes to the page.
// /app/page.js
import react, { useEffect, useState } from 'react'
export default Page() {
const [myData, setMyData] = useState([]);
// this is calling a router handler
const getData = async () => {
const response = await fetch('/api/data', {
method: 'GET',
});
if (response.ok) {
console.log('Response.Ok');
const { data } = await response.json();
setMyData((prev) => data);
} else {
console.log('Error');
}
};
useEffect(() => {
getData();
}, [])
return (<div>{myData.map((item, index)=>(<div>item.name</div>)}</div>)
}
2
Answers
React Strict mode is turned off by default in NextJS v13.4
app router
. With some experimenting of how many times the useEffect runs, I can confirm that strict mode is off by default.Going to the file
next.config.js
at the root of the project, you will see the following.H/T to the comments and answers who referenced React Strict mode.
The component is pure, a problem is most likely in the parent component. Perhaps some props are changing, thereby causing child components to re-render.
Remember: child components will not re-render and then trigger its lifecycle hooks if parent component pass it like that
{children}
– directlyAnd don’t forget about React strict mode: https://stackoverflow.com/a/60619061/15604836