0

I am using many useCallbacks in useEffects in the same format syntax and feel like shortening them. So, I map them in this hook. effects is an array of useCallback functions.

import React from 'react';
    const useEffects = (effects: Function[]) =>
      effects.map((effect) =>
        React.useEffect(() => {
          effect();
        }, [effect])
      );
export default useEffects;
  • 2
    Yes, you can't `useEffect` inside a callback – CertainPerformance May 17 '21 at 03:31
  • React hooks should be called at the top-most scope of a component, please check https://reactjs.org/docs/hooks-rules.html#only-call-hooks-at-the-top-level – TopW3 May 17 '21 at 03:36
  • i believe you can't use hooks inside an array. Because we don't know the length of the array. And all hooks are registered based on their physical location order. – windmaomao May 17 '21 at 03:53

1 Answers1

0

Hooks can't be defined inside an array.

I wrote an article recently about the rendering order of hooks. https://windmaomao.medium.com/understanding-hooks-part-4-hook-c7a8c7185f4e

It really goes down to below snippet how Hooks is defined.

function hook(Hook, ...args) {
  let id = notify()
  let hook = hooks.get(id)
  if(!hook) {
    hook = new Hook(id, element, ...args)
    hooks.set(id, hook)
  }
  return hook.update(...args)
}

When a hook is registered, it requires an unique id, as in line notify(). Which is just a plain i++ placed inside the Component where the hook is written inside.

So if you have a fixed physical location of the hook, you have a fixed id. Otherwise the id can be random, and since the render Component function is called every render cycle, a random id is not going to find the right hook in the next render cycle.

That is why if can not be written before the hook statement either. Just try

  const Component = () => {
    const b = true
    if (!b) return null
    const [a] = useState(1)
  }

You should get similar error.

windmaomao
  • 7,120
  • 2
  • 32
  • 36