10

In Next-JS, UseEffect() is run twice. I heard that you need to put an empty array as the second argument to fix this in React. In my case, in Next-JS, this does not work. (As far as I know, Next-JS is based on React).

I found one way: in next.config.js set reactStrictMode: false. And it works, the UserEffect is called once.

But this method does not suit me, because. I need to use React's strict mode.

_app.js:

import '../styles/globals.css';
import React, { useEffect, useState, useRef } from 'react';

function MyApp({ Component, pageProps }) {
  if (typeof window !== "undefined") {
    useEffect(() => {

      console.log('Component Did Mount') //called twice :c

    }, [])


  return <Component {...pageProps} />
}


export default MyApp
Alexei
  • 277
  • 1
  • 2
  • 9
  • 3
    Are you using react 18? If so, it is [expected behavior in strict mode](https://reactjs.org/blog/2022/03/29/react-v18.html#new-strict-mode-behaviors) that the component mounts twice, which means the effect will run twice. – Nicholas Tower Apr 21 '22 at 16:36
  • 1
    btw, you can remove the condition. useEffect only runs client-side, so window is guaranteed to be defined. [docs](https://nextjs.org/docs/migrating/from-create-react-app#safely-accessing-web-apis) – szaman Apr 21 '22 at 16:45
  • 2
    From the react docs: Don’t call Hooks inside loops, conditions, or nested functions. https://reactjs.org/docs/hooks-rules.html – Brandon Piña Apr 21 '22 at 16:57
  • For a in depth answer https://stackoverflow.com/questions/72238175/react-18-useeffect-is-getting-called-two-times-on-mount/72238236#72238236. – Youssouf Oumar Sep 21 '22 at 15:54

1 Answers1

17

React.StrictMode is used to help during development, so why are you concerned about the double execution ? By the way the rules of hooks say that you cannot place an hook inside a loop or an if statement.

Here are the code examples to address both issues:

  1. NextJS to config React's Strict Mode edit next.config.js file
module.exports = {
    reactStrictMode: false,
}
  1. Move your if statement inside the useEffect hook
import { useEffect } from 'react';

function MyApp({ Component, pageProps }) {
    useEffect(() => {
    if (typeof window !== "undefined") {
        console.log('Component Did Mount') // called once
    }, [])

    return <Component {...pageProps} />
}

export default MyApp
Cesare Polonara
  • 3,473
  • 1
  • 9
  • 19
  • 1
    For a more detailed answer: https://stackoverflow.com/questions/72238175/why-useeffect-running-twice-and-how-to-handle-it-well-in-react. – Youssouf Oumar May 06 '23 at 08:01