Making a Custom Visibility React Hook
Published on Oct 29, 2020 by Ben Tyler
React Hooks are fantastic. They have have greatly streamlined my codebase and made it easier to develop and maintain complex components. This post is not going to be a primer on hooks. If you are not familiar with hooks, go check out the React docs or this tutorial by Kent C. Dodds on Egghead.
A lot of the apps I build make use of components like drawers and dialogs. These components require that I track their visibility state (i.e. open or closed). Nothing too complex here. Most of the time you can just handle this through the useState
hook. However, I found that in some instances I wanted to explicitly set the visibility state to true
or false
and in some instances I just wanted to toggle the current state. Again, easy enough.
I got tired of writing the same logic across multiple components though and decided to refactor things into a custom useVisibility
hook. The hook returns the current state value as well as a handler for updating the visibility state. The update handler takes an optional value argument. If the value argument is provided, it sets the state to the provided value. If no value argument is provided, it sets the state to the opposite of the current value. Here is the hook in its entirety as well as sample usage in a fictional blog post component. Thanks for reading!
import { useState } from "react"const useVisibility = (defaultVisibility = false) => { const [visibility, setVisibility] = useState(defaultVisibility) const handleVisibility = value => { if (value && typeof value === "boolean") { setVisibility(value) } else { setVisibility(state => !state) } } return [visibility, handleVisibility]}export default useVisibility
And here is an example usage for for a dialog component in a fictional blog post component.
import React from "react"import Layout from "components/Layout"import Button from "components/Button"import Article from "components/Article"import Dialog from "components/Dialog"import useVisibility from "hooks/useVisibility"const Post = ({ data }) => { const [dialogVisibility, handleDialogVisibility] = useVisibility(false) return ( <Layout> <Article data={data} /> <Button onClick={() => handleDialogVisibility(true)}> Join Our Newsletter </Button> <Dialog open={dialogVisibility} onClose={() => handleDialogVisibility(false)} > {/* ..some sort of sign up form here */} </Dialog> </Layout> )}export default Post
About Me
Howdy, I am Ben Tyler. I am a product-focused engineer who cares deeply about finding the simplest solution to a user's problem.
I love collaborating on projects, so if you need a hand, please schedule a call or get in touch at hello@lostcreekdesigns.co!
Schedule a Call!