2

I have a requirement not to execute the code inside useEffect() when the component renders for the first time. For that, I defined a variable outside of the component function and set it to true. And then I checked if the variable is true inside useEffect() hook and if it was true, I set the variable to false and set it to return as shown below. But the code is not working as I expected. The code inside useEffect() executes regardless.

import { useEffect, useState } from 'react';

let isInitial = true;

function App() {
  const [message, setMessage] = useState('First');

  useEffect(() => {
    if (isInitial) {
      isInitial = false;
      return;
    }
    setMessage('Executed');
  }, []);

  return <p>{message}</p>;
}

export default App;

I wanted to print 'First' inside the <p>. But the result was 'Executed' inside <p> which is not what I expected.

3
  • your code seems to be ok , I tried that in and it shows 'First' Commented Nov 13, 2022 at 6:43
  • @AliSattarzadeh for me, it shows "First" briefly and then it gets replaced with "Executed". I created this Codesandbox to demonstrate the issue I'm having Commented Nov 13, 2022 at 7:06
  • It is probably because you are in react strict mode and running react 18. Try removing <React.StrictMode> from your app file and it should work Commented Nov 13, 2022 at 7:09

2 Answers 2

1

Strict Mode would be the problem. It renders your component twice in development mode. So the result would be not what you need in your code.

In addition, I suggest you to change the let statement to useState. Changing mutable let in the useEffect would cause unexpectable side effects. Using useState would be more predictable, React way.

import { useEffect, useRef, useState } from "react";

function App() {
  const [message, setMessage] = useState("First");
  const [isInitial, setIsInitial] = useState(true);

  useEffect(() => {
    if (isInitial) {
      setIsInitial(false);
    } else {
      // Do what you want excepts first render
    }
  }, [isInitial]);

  return <p>{message}</p>;
}

export default App;
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you @Jay. Yes, Strict mode was the issue. I will change let variable to a state inside the component.
1

The code you wrote should result <p>First</p>, unless <React.StrictMode> has wrapped around your main component (StrictMode is a tool for highlighting potential problems in an application and the checks are run in development mode only). It causes App component to render twice and useEffect callback function will be called twice too(although the useEffect has [] dependency).

You should remove that wrapper.

1 Comment

Thanks, @mahooresorkh. Yes, <React.StrictMode> was the issue. When I removed <React.StrictMode> wrapper, the code worked fine.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.