Top 10 React Hook libraries

Hooks came and took the React community by the storm. But, since it’s been a while since their initial release, there are now lots of supporting libraries.

It is extremely hard not to stumble upon the “hooks” word while searching for anything related to React, so if you haven’t already, you should pick them up into your codebase as soon as possible. They will make your coding life much easier and more enjoyable.

Keeping a clean code style, ensuring readability, maintainability, and reusability, and having fewer lines of code is crucial in React development, so in this blog, I’ll present to you the top 10 React Hook libraries which you should start using immediately. Without further delay let’s get on the way.

1. use-http

use-http is an incredibly useful package that is used as a replacement for Fetch API. Written and maintained with high quality, it makes your coding much simpler and understandable with a special emphasis on the data consumption part. The hook itself uses TypeScript and even has support for SSR and GraphQL. It returns a response, loading, error data and different request methods such as Get, Post, Put, Patch and Delete.

Main features it provides are:

  1. Request/Response interceptors
  2. Suspense (experimental currently)
  3. Retry functionality
  4. Caching

It is well documented with both CodeSandbox examples and Youtube videos together with GitHub readme.

Usage example:

import useFetch from "use-http"

const Example = () => {
  const [todos, setTodos] = useState([])
  const { get, post, response, loading, error } = useFetch("https://example.com")
  
  useEffect(() => { get("/todos") }, [])

  const addTodo = async () => {
      await post("/todos", { title: "example todo" });
      if (response.ok) setTodos([...todos, newTodo])
  }

  return (
    <>
      <button onClick={addTodo}>Add Todo</button>
      {error && 'Error!'}
      {loading && 'Loading...'}
      {todos.map(todo => (
        <span key={todo.id}>{todo.title}</span>
      )}
    </>
  );
};

2. useMedia

Have you ever needed a way of tracking the CSS media query? The useMedia hook provides a simplistic approach to the problem. It is a sensory hook which tracks exactly that. Media queries are really important as well as the responsiveness of any app or website.

Written in TypeScript, this Hook offers its support. The package has well-defined documentation that explains the usage, as well as the testing methods for the hook.

Usage example:

import useMedia from 'use-media';

const Example = () => {
  const isWide = useMedia({minWidth: '1000px'});

  return (
    <span>
      Screen is wide: {isWide ? "WideScreen" : "NarrowScreen"}
    </span>
  );
};

3. Constate

Constate is a hook package that provides lifting local state up to React Context. It means that any state from any component can be easily lifted to the context with minimum effort. This is useful in cases where you would like to use the same state in multiple spots, or provide the same state to multiple components. The name comes from a wordplay merging Context and State.

It is written in Typescript and is very small in size. The documentation is not so detailed, but it gets the job done.

Usage example:

import React, { useState } from "react";
import constate from "constate";

// custom hook
function useCounter() {
  const [count, setCount] = useState(0);
  const increment = () => setCount(prevCount => prevCount + 1);
  return { count, increment };
}

// hook passed in constate
const [CounterProvider, useCounterContext] = constate(useCounter);

function Button() {
  // use the context
  const { increment } = useCounterContext();
  return <button onClick={increment}>+</button>;
}

function Count() {
  // use the context
  const { count } = useCounterContext();
  return <span>{count}</span>;
}

function App() {
  // wrap the component with provider
  return (
    <CounterProvider>
      <Count />
      <Button />
    </CounterProvider>
  );

4. Redux hooks

Redux is a well-known tool for many, if not all, React developers. It is used as a global state manager throughout the application. It went onboard with hooks a couple of months after React’s initial release. It offers an alternative to the HOC (Higher Order Component) pattern with the existing connect() method.

The most notable hooks provided are:

  1. useSelector
  2. useDispatch
  3. useStore

The documentation is quite good – a bit complex, but it will provide you with any information needed to start using them.

Usage example:

import {useSelector, useDispatch} from "react-redux";
import React from "react";
import * as actions from "./actions";

const Example = () => {
const dispatch = useDispatch()
const counter = useSelector(state => state.counter)

return (
<div>
   <span>
     {counter.value}
   </span>
   <button onClick={() => dispatch(actions.incrementCounter)}>
     Counter +1
   </button>
</div>
);
}

5. React hook form

React hook form is a form hook library which is similar to the Formik and Redux form, but better. With its much simpler syntax, speed, less rerenders and better maintainability, it started to climb the GitHub ladders.

It is tiny in size and built with performance in mind. The library even offers its form builder which is great. And it has one of the biggest amounts of GitHub starts for a React hooks library – 14.8k.

Usage example:

import React from "react";
import { useForm } from "react-hook-form";

function App() {
  const { register, handleSubmit, errors } = useForm();
  const onSubmit = (data) => {
    // logs {firstName:"exampleFirstName", lastName:"exampleLastName"}
    console.log(data);
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input name="firstName" ref={register} />
      <input name="lastName" ref={register({ required: true })} />
      {errors.lastName && <span>"Last name is a required field."</span>}
      <input name="age" ref={register({ required: true })} />
      {errors.age && <span>"Please enter number for age."</span>}
      <input type="submit" />
    </form>
  );
}

6. useDebounce

useDebounce represents a small hook that is used for debouncing. It is used to postpone function execution to a later time, and it is also often used in inputs and forms which fetch data.

Usage example:

import React, { useState } from "react";
import { useDebounce } from "use-debounce";

export default function Input() {
  const [text, setText] = useState("Hello");
  const [value] = useDebounce(text, 1000);

  return (
    <div>
      <input
        defaultValue={"Hello"}
        onChange={(e) => {
          setText(e.target.value);
        }}
      />
      <p>Value: {text}</p>
      <p>Debounced value: {value}</p>
    </div>
  );
}

7. useLocalStorage

useLocalStorage is a small hook just like the one above. It is really useful for extracting and setting the data inside localStorage. With it, manipulation is made easy.

It offers automatic JSON serialization and synchronization across multiple tabs and is written in TypeScript so it offers types.

Documentation is written in a quality manner and is quite understandable with extended examples.

Usage example:

import React, { useState } from "react";
import { writeStorage } from '@rehooks/local-storage';

export default function Example() {
  let counter = 0;
  const [counterValue] = useLocalStorage('counterValue');

  return (
    <div>
      <span>{counterValue}</span>
      <button onClick={() => writeStorage('i', ++counter)}>
        Click Me
      </button>
    </div>
  );
}

8. usePortal

usePortal makes the creation of dropdowns, modals, notification popups, tooltips… super easy! It also enables the creation of elements outside the DOM hierarchy of the App (to learn how Portals work, click here).
This hook works with SSR as is isomorphic. It is written in TypeScript and has a built-in state. As for functions, it offers the full customization of the portal styling and ton of other options.

Documentation written for it is quite good – it shows many examples which will be more than enough to start using the library/hook yourself.

Usage example:

import React, { useState } from "react";
import usePortal from "react-useportal";

const Example = () => {
const { ref, openPortal, closePortal, isOpen, Portal } = usePortal()

    return (
      <>
    <button ref={ref} onClick={() => openPortal()}>
       Open Portal
    </button>
     {isOpen && (
       <Portal>
         <p>
           This Portal handles its own state.{' '}
           <button onClick={closePortal}>Close me!</button>, hit ESC or
           click outside of me.
         </p>
       </Portal>
     )}
       </>
 )
}

9. useHover

useHover is a React state hook that determines if a React element is being hovered. It’s really easy and intuitive to use. The library itself is small, and simple to use, but can be very powerful if you’re creative enough.

It offers the delay of the hover effect, and it’s TypeScript supported. The documentation is not as detailed, but it will show you how to use it fairly well.

Usage example:

import useHover from "react-use-hover";

const Example = () => {
  const [isHovering, hoverProps] = useHover();
  return (
    <>
      <span {...hoverProps} aria-describedby="overlay">Hover me</span>
      {isHovering ? <div> I’m a little tooltip! </div> : null}
    </>
  );
}

10. React router hooks

React router is one of the most popular libraries for React. It is used for routing and getting the app URL history etc.
Along with Redux, it has implemented its hooks for getting a variety of useful data.

Hooks offered are:

  1. useHistory
  2. useLocation
  3. useParams
  4. useRouteMatch

Their names are pretty self-explanatory, but here’s a quick rundown. UseHistory will get the data of the app’s history and methods such as push which pushes to a new route. UseLocation will return the object that represents the current URL. UseParams will return an object of key-value pairs of URL params of the current route. And finally, useRouteMatch will attempt to match the current URL with the given one which can be a string or an object of different options.

The documentation for this library is good and it’s written with many examples

Usage example:

import { useHistory, useLocation, useRouteMatch } from "react-router-dom";

const Example = () => {
let history = useHistory();
let location = useLoction();
let isMatchingURL = useRouteMatch("/post/11");

function handleClick() {
history.push("/home");
}

return (
<div>
<span>Current URL: {location.pathname}</span>
{isMatchingURL ? <span>Matching provided URL! Yay! </span> : null}
<button type="button" onClick={handleClick}>
Go home
</button>
</div>
);
}

A lot more to choose from

There are many more hook libraries out there, but these are the ones I currently find the most useful. If you do happen to like them a lot, go and support them in any way.

The hooks are still a relatively new way of doing this, but they are here to stay. and in further months we expect even more brilliant libraries and hook examples to rise up to the surface. Hope you have found this post interesting, and that you have learned something new. Have fun in your further exploration of the hooks!