This blog post is just a note for me, my colleagues, and any Next.js developers who have met double dipping useEffect with Next.js. It is a pretty common problem and sometimes we simply want to avoid it for some reasons, such as we don’t want double dipping the request in local development environment. If you are worrying about the production, then you are good to go because this behavior should not exist in production.
As far as I know when browsing a solution online, I have found a lot of discussions such that this behavior could be easily avoided by disabling strict mode in Next.js config file. However, sometimes we just don’t want to disable it or we are not allowed to disable it. Then, this solution is for you.
The workaround is also pretty simple, as long as you don’t need server-side rendering here:
import React, { useEffect, useState } from 'react';
const [isMounted, setIsMounted] = useState<boolean>(false);
useEffect(() => {
setIsMounted(true);
}, []);
// IMPORTANT: If you are having other hooks, you need to put it here.
if (!isMounted) {
// TODO: Or anything you want to fit your typing.
// Such as (<></>).
return null;
}
return (...);
This should simply resolve your problem. But, if you have other hooks, it is recommended (by React official) to put before any branch return. Therefore, you should consider replacing the code like this:
// Replace from:
useEffect(() => {
// Your logic. It should only execute once,
// but gets executed twice in local development.
}, []);
// Replace to:
useEffect(() => {
if (isMounted) {
// Your logic. It will only execute once! Yeah!
}
}, [isMounted]);
Pretty simple, right? Hope this helps!
November 15, 2023