55

How I can skip first run in useEffect hook.

useEffect(() => {
    const first = // ???
  if (first) {
    // skip
  } else {
    // run main code
  }
}, [id]);
seyed
  • 1,555
  • 1
  • 17
  • 24

1 Answers1

138

The useRef hook can be used to store any mutable value, so you could store a boolean indicating if it's the first time the effect is being run.

Example

const { useState, useRef, useEffect } = React;

function MyComponent() {
  const [count, setCount] = useState(0);

  const isFirstRun = useRef(true);
  useEffect (() => {
    if (isFirstRun.current) {
      isFirstRun.current = false;
      return;
    }

    console.log("Effect was run");
  });

  return (
    <div>
      <p>Clicked {count} times</p>
      <button
        onClick={() => {
          setCount(count + 1);
        }}
      >
        Click Me
      </button>
    </div>
  );
}

ReactDOM.render(
  <MyComponent/>,
  document.getElementById("app")
);
<script src="https://unpkg.com/react@16.7.0-alpha.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16.7.0-alpha.0/umd/react-dom.development.js"></script>

<div id="app"></div>
Tholle
  • 108,070
  • 19
  • 198
  • 189
  • 2
    Do you see any benefits in using useRef vs useState in this case? – Estus Flask Nov 17 '18 at 13:18
  • 15
    @estus Using e.g. `const [isFirstRun, setFirstRun] = useState(true);` and using `setFirstRun` the first time the effect is run would cause a re-render, which might not be what you want. – Tholle Nov 17 '18 at 13:20
  • 2
    That's a good point, thanks for sharing. This actually was the problem with my own implementation I noticed. – Estus Flask Nov 17 '18 at 13:31
  • 2
    Why not simply `let isFirstRun = true;` ? – Nicolas Zozol Oct 01 '19 at 16:38
  • 5
    @NicolasZozol A regular boolean would not be persisted between renders. You need a ref for that. – Tholle Oct 01 '19 at 19:17
  • 1
    I've seen that. In fact you could use let isFirstRun={value:true} *outside* the function and change `isFirstRun.value=false`. That's not more simple :) – Nicolas Zozol Oct 02 '19 at 09:02
  • 1
    I had the same question: what would be the downside of declaring the variable outside of the function and setting its value inside of the function? i.e. `let isFirstRun; ... function MyComponent() { useEffect(() => { isFirstRun = false; }) ... }` – John Karahalis Oct 04 '19 at 00:29
  • 7
    A variable that is declared outside the function is shared by ALL instances of the component. – Tomasz Szuba Oct 04 '19 at 10:17
  • 6
    **Note**: If you are using multiple useEffects that check for isFirstRun, make sure only the last one (on bottom) is setting isFirstRun to false. React goes through useEffects in order! – Dror Bar Apr 18 '21 at 11:06
  • Note: The example code should be as follows if (isFirstRun.current === true) { isFirstRun.current = false; return; } since 'isFirstRun.current' is not undefined or null, you need an explicit comparison. – Egbert Nierop Aug 15 '23 at 14:01