React Hooks and Conditions

Viewed 107

The "Rules of Hooks" mention:

Don’t call Hooks inside loops, conditions, or nested functions.

Does that also mean we should avoid code like this?

const useMyCoolHook = ({configKey, anotherProp}) => {
  useEffect(() => {
    // Do something with configKey here
  }, [configKey])

  useEffect(() => {
    // Do something with configKey and anotherProp here
  }, [configKey, anotherProp])
}

const Component = ({configKey, anotherProp}) => {
  if(configKey === undefined) { return null; }

  useMyCoolHook({configKey, anotherProp})

  return (
    <h1>Hello world</h1>
  )
}

If so, is there a way to avoid having to include the condition inside each of the useEffect hooks?

1 Answers

The code you have so far looks like a normal curstom hook. However; the way you call it is wrong, the linter should give you the following warning:

React Hook "useMyCoolHook" is called conditionally. React Hooks must be called in the exact same order in every component render. Did you accidentally call a React Hook after an early return?

The following will have the linter stop giving you warnings but you have to repeatedly check for the value of configKey:

const useMyCoolHook = ({ configKey, anotherProp }) => {
  useEffect(() => {
    if (configKey !== undefined) {
      // Do something with configKey here
    }
  }, [configKey]);

  useEffect(() => {
    if (configKey !== undefined) {
      // Do something with configKey and anotherProp here
    }
  }, [configKey, anotherProp]);
};

const Component = ({ configKey, anotherProp }) => {
  useMyCoolHook({ configKey, anotherProp });
  if (configKey === undefined) {
    return null;
  }

  return <h1>Hello world</h1>;
};

A wrapper component is another option to check configKey before attempting to render Component

const ComponentWrapper = ({configKey, anotherProp}) => {
  if (configKey) {
    return <Component configKey={configKey} anotherProp={anotherProp}/>
  }
  else {
    return null;
  }
}
Related