Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I call hooks conditionally in React if the conditions won't change across the component's lifetime?

function Component({ condition }) {
  const initialCondition = useMemo(() => condition, [])
  const state = initialCondition ? useHook1() : useHook2()
  return <h1>{state}</h1>
}

If we know the value initialCondition will not change it throughout the life of the component, can it be used as a conditional statement specifying which hook to use?

Through experience, there were no problems, there are not many problems

like image 488
zohayr slileh Avatar asked Nov 01 '25 19:11

zohayr slileh


1 Answers

As pointed out in the question comments, there are "Rules of Hooks" which in particular state:

Do not call Hooks inside conditions or loops.

But as also noted, the actual hard technical requirement behind that rule, is that React needs that whenever a Component re-renders, all its called Hooks must be exactly the same, in the exact same order. Kind of a fingerprint.

The Rule just enforces this requirement, in a manner that is easy to follow for developers and linting tools.

While you can break the Rule, as long as you ensure somehow that the exact same Hooks are run in the exact same order for a given Component instance, then indeed, React will not crash.

But you can easily accommodate your use case to that Rule, combining the suggestions in the question comments:

function Component({ condition }) {
  // No conditional Hook
  return <h1>
    { condition // The condition is used to select Components, not Hooks
      // If the condition changes, it destroys the child Component instance and creates a new one,
      // instead of calling a different Hook, which would break React
      ? <ComponentWithHook1 /> // No condition passed
      : <ComponentWithHook2 />
    }
  </h1>
}

function ComponentWithHook1() {
  const state = useHook1() // Hook at the root level of the Component body
  return <>{state}</>
}

function ComponentWithHook2() {
  const state = useHook2()
  return <>{state}</>
}
like image 181
ghybs Avatar answered Nov 04 '25 10:11

ghybs