Home > front end >  What happens for an useEffect with the second argument is null or undefined?
What happens for an useEffect with the second argument is null or undefined?

Time:06-27

I just wanted to know how useEffect will behave if we pass the second argument as null or undefined in place of the dependencies array. Will it render on every cycle? Or just once? Any leads will be appreciated.

CodePudding user response:

If you create an useEffect with the second argument undefined or null, yes the callback will gets executed on every render.

That's okay in a case like below where you don't mutate a state inside the callback, it will just log "Hello Word" every time there is a render.

export default function App() {
  const [state, setState]= useState(true);
  useEffect(() => {
    console.log("Hello Word");
  });
  return (
    <div>
      <button onClick = {()=>setState(!state)}>Toggle State</button>
    </div>
  );

It will cause an infinite loop of renders in case like below where you mutate a state inside the callback. That's because a state change trigger a render, and the callback gets executed on every render.

export default function App() {
  const [state, setState]= useState(true);
  useEffect(() => {
   setState(!state);
  });
  return (
    <div>
      <button onClick = {()=>setState(!state)}>Toggle State</button>
    </div>
  );

And to cover all the use cases, there is the one with an empty dependencies array as second argument, where the callback gets executed only on first render:

export default function App() {
  const [state, setState]= useState(true);
  useEffect(() => {
   setState(!state);
  },[]);
  return (
    <div>
      <button onClick = {()=>setState(!state)}>Toggle State</button>
    </div>
  );

And finally the one that calls the callback on first render and every time some state in the dependencies array changes:

export default function App() {
  const [state, setState]= useState(true);
  useEffect(() => {
   console.log("Hello Word");
   // setState(!state); if you mutate state here, it will cause an infinite loop of renders
  },[state]);
  return (
    <div>
      <button onClick = {()=>setState(!state)}>Toggle State</button>
    </div>
  );

CodePudding user response:

It will rerender every circle if deps is not defined or is null.

In react source, when second argument not defined, deps will be null, updateEffectImpl, will always execute pushEffect, and render every circle :

function updateEffectImpl(fiberFlags, hookFlags, create, deps): void {
  const nextDeps = deps === undefined ? null : deps;

  if (currentHook !== null) {
    // .eg
  }

  // always execute
  hook.memoizedState = pushEffect(
    HookHasEffect | hookFlags,
    create,
    destroy,
    nextDeps,
  );
}
  • Related