How to use custom hooks with React

March 16, 2021 ∙∙∙ views 2 min read

If you're familiar with React I'm sure you've used some hooks by now.

Hooks such as useState or useEffect. It can come in hand using custom hooks from times to times.


For this purpose, lets picture you have an application where your users can manage permissions within the app, say, an admin can manage their users permissions. Now, you have those stored in the database (obviously), with custom hooks we can easily apply the DRY method in our application.

userIdproductsPageinvoicesPage
1truefalse

We can easily see that this user has access to the products page, but not to the invoices page.

To keep it simple I'll use swr from Vercel. Imagine we have an API endpoint where it fetches the permissions of the authenticated user.

In our products page:

import useSWR from 'swr'

const ProductsPage = () => {
  const { data, error } = useSWR('/api/user/permissions')

  if (!data) return <>Loading ...</>
  if (!data.productsPage) return <>You don't have access... </>

  return (
    <>
      Welcome to the products page!
    </>
  )
}

By replacing productsPage with invoicesPage we can re-use this code in the invoices page, this is where using a custom hooks is helpful.


Custom Hook

We'll call our hook usePermissions. Lets take a look at how would that look like:

import useSWR from 'swr'

export default function usePermissions() {
  const { data, error } = useSWR('/api/user/permissions')
  const loading = data === undefined

  return {
    permissions: data,
    loading,
    error,
  }
}

We can now re-use this hook wherever we want within our application, lets change our products component to take advantage of usePermissions:

import useSWR from 'swr'

import usePermissions from './hooks/usePermissions'

const ProductsPage = () => {
  const { permissions, loading } = usePermissions()

  if (loading) return <>Loading ...</>
  if (!permissions.productsPage) return <>You don't have access... </>

  return (
    <>
      Welcome to the products page!
    </>
  )
}

Although it can look pretty similar, trust me, it's better this way. Imagine you need to change the logic on how to fetch permissions, you only need to change your usePermissions hook, still exporting permissions.

That's it ✌️