The Key to Calling React Hooks Conditionally
2 min readOne of the first rules of using hooks is to not call them conditionally. However, the need may arise where you’re in a situation, and you would rather not use components to abstract hook logic. While there is a solution to this problem, please remember there’s a reason it’s not recommended, and the following code could introduce performance issues or unneeded complexity.
Keys to the rescue
Key is an essential attribute in React, and you’ve probably seen the same warning we all have when looping over data to render. They help identify instances and allow React to make optimizations (this is why you should never rely on index as a key).
Knowing that keys help with identity, we can change a component’s key whenever we want to remount the component as if it was the first time we see it. This ability to remount a component when we please is where we can utilize keys to swap out an underlying hook.
We’ll start with two custom hooks that both update the component after it has mounted:
1function useText() {2 const [text, setText] = React.useState('')3 React.useLayoutEffect(() => {4 setTimeout(() => {5 setText('Hello')6 setTimeout(() => {7 setText((text) => text + ' World')8 }, 1000)9 }, 1000)10 }, [])11 return text12}1314function useCount() {15 const [count, setCount] = React.useState(0)16 React.useLayoutEffect(() => {17 const id = setInterval(() => {18 setCount((count) => count + 1)19 }, 1000)20 return () => {21 clearInterval(id)22 }23 }, [])24 return count25}
Now in a simple App
example, we’ll toggle between our useCount
and useText
hook:
By changing the key
at the same time as our logic responsible for swapping the hooks, everything works as expected since the component is fully remounted.
Conclusion
While there is a way to make conditional hooks work, they are not practical. It creates a dependency between your parent and child components and is just an awkward API. Not to mention if you have complex logic going on in your component, remounting each time could have an affect on performance. If you need conditional logic in hooks, use either separate components or render all hooks every time and use booleans inside each hook to turn features on/off.
Resources
How to break the rules of React Hooks
- development
- react
- hooks