There are times when we want some React state that should always hold a boolean value, and should only allow toggling between true and false.

This is a thin wrapper around React.useState to solve for this purpose. It carries greater semantic meaning, and prevents us from accidentally setting a non-boolean value in the future.


The nice thing about this hook is that the toggleIsOn function can be passed straight to a click-handler; there's no need for an intermediary arrow that sets the value to the opposite of the value (and no opportunity for accidentally setting it to a non-boolean value!).

This hook uses React.useCallback in order to preserve the reference to the setter function; without this wrapper, the toggle function would be recreated on every render.

The cost of creating this function is minimal, but recreating it means that it would be a new reference. This would break memoization of children elements.

For example, say we have this code:


A button can be clicked to increment a counter bit of state. Whenever that button is clicked, App will re-render.

Because SomeBigComponent is wrapped with React.memo, it will only re-render when its props change. And it only has one prop, the toggleIsOn function.

Without the React.useCallback in our useToggle hook, that toggleIsOn function would change on every render! This means that SomeBigComponent would re-render even when the user is incrementing the count by clicking the button.

In practice, this likely won't be a huge performance problem in most cases, but because useToggle is generic and reusable, it doesn't hurt to bake this in.