souporserious

The Key to Calling React Hooks Conditionally

2 min read

One 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 text
12}
13
14function 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 count
25}

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

Updated:
  • development
  • react
  • hooks
Previous post
Build a Simple FLIP Animation in React
Next post
Getting Started with Figma Webhooks