React’s Hooks API is now the de facto method for creating components. It coexists alongside the class component API, which lets us create components with JavaScript classes.
In addition to the standard Hooks that come with the React library, developers can create their own Hooks. Unsurprisingly, many custom Hooks libraries have since popped up to make creating React apps even easier.
In this article, we’ll look at five useful React Hooks libraries and compare their utility
1. React Hooks Lib
React Hooks Lib provides us with Hooks that resemble the lifecycle methods of React class components.
For example, it offers Hooks like useDidMount
, which runs when the component is mounted, and useDidUpdate
, which runs when the component updates. It also has Hooks for managing states, like useCounter
, which add a number state with its own functions to manage it.
To install the package, we can run:
npm i react-hooks-lib --save
Then we can use some of the Hooks by importing them from the module. We can use the useDidMount
Hook by writing:
import React from "react"; import { useDidMount } from "react-hooks-lib"; export default function App() { useDidMount(() => { console.log("did mount"); }); return ( <div className="App"> <h1>Hello world</h1> </div> ); }
Likewise, we can use the useCounter
Hook by writing:
import React from "react"; import { useCounter } from "react-hooks-lib"; export default function App() { const { count, inc, dec, reset } = useCounter(0); return ( <div> {count} <button onClick={() => inc(1)}>increment</button> <button onClick={() => dec(1)}>decrement</button> <button onClick={reset}>reset</button> </div> ); }
It returns an object with the count
state and the inc
, dec
, and reset
methods. Let’s break down what these methods do:
inc
incrementscount
by a given numberdec
decrementscount
by a given numberreset
resets thecount
to the initial value
React Hooks Lib also comes with the useField
Hook to make getting and setting input values easier. We can use it by writing:
import React from "react"; import { useField } from "react-hooks-lib"; export default function App() { const { value, bind } = useField("text"); return ( <div> <input type="text" {...bind} /> <p>{value}</p> </div> ); }
We just pass the whole bind
object into the input, and we can use it to get the data from the input and set it as the value of value
. bind
also has the value
property to set the input value.
It also works with select elements:
import React from "react"; import { useField } from "react-hooks-lib"; export default function App() { const { value, bind } = useField("text"); return ( <div> <select {...bind}> <option value="apple">apple</option> <option value="orange">orange</option> </select> <p>{value}</p> </div> ); }
React Hooks Lib comes with many other Hooks that provides similar functionality. Overall, it provides us with custom Hooks that can do a few convenient things. We should note, however, that not all the provided Hooks are documented.
2. react-hanger
react-hanger is a library that provides us with React Hooks to let us more easily manage various kinds of states. It comes with the following Hooks:
useInput
– get and set input control valuesuseBoolean
– get and set Boolean statesuseNumber
– get and set number statesuseArray
– get and set array statesuseOnMount
– run code when a component mountsuseOnUnmount
– run code when a component unmountsuseStateful
– get and set component state
We can use useInput
to as follows to make processing input values simpler:
import React from "react"; import { useInput } from "react-hanger"; export default function App() { const input = useInput(""); return ( <div> <input type="text" value={input.value} onChange={input.onChange} /> <p>{input.value}</p> </div> ); }
We can use the useNumber
to get and set a number state:
import React from "react"; import { useNumber } from "react-hanger"; export default function App() { const counter = useNumber(3, { lowerLimit: 0, upperLimit: 5 }); return ( <div> <p> {counter.value} </p> <button onClick={() => counter.increase()}> increase </button> <button onClick={() => counter.decrease()}> decrease </button> </div> ); }
We can set counter.value
‘s initial value with the first argument, and we can set the lower and upper limit of the counter.value
state with the second. The useArray
and useBoolean
Hooks work in a similar way.
To set any kind of state, we can use the useStateful
Hook:
import React from "react"; import { useStateful } from "react-hanger"; export default function App() { const username = useStateful("tom"); return ( <div> <p> {username.value} </p> <button onClick={() => username.setValue("tom")}> tom </button> <button onClick={() => username.setValue("jerry")}> jerry </button> </div> ); }
It’s better than React’s useState
Hook in that we can get the value of the state from the value
property, and we can set the value with the setValue
method of the returned object. No destructuring is required to get the state and setter function, unlike React’s inbuilt useState
Hook.
3. React hookedUp
Like countless other libraries, React hookedUp lets us manage component states. But we can also use it to manage focus and hovering of HTML elements.
It comes with Hooks that replicate the functionality of class component lifecycle Hooks, as well as a few useful timer and network Hooks that aren’t provided by the other libraries we’ve reviewed so far.
Let’s take a look at the useHover
Hook, which will detect if we hover over an input:
import React from "react"; import { useHover } from "react-hookedup"; export default function App() { const { hovered, bind } = useHover(); return ( <div> <p>{hovered ? "hovered" : "not hovered"}</p> <input {...bind} /> </div> ); }
We just spread the whole bind
object as props for the input
. The useFocus
Hook can be used in a similar way.
If we miss our good ol’ componentDidMount
method in class components, we can use the useOnMount
Hook to provide equivalent functionality in function components:
import React from "react"; import { useOnMount } from "react-hookedup"; export default function App() { useOnMount(() => console.log("mounted")); return <div> hello world </div>; }
And if we want to call setInterval
in our code, we can use the useInterval
Hook. For example, we can write:
import React, { useState } from "react"; import { useInterval } from "react-hookedup"; export default function App() { const [time, setTime] = useState(new Date().toString()); useInterval(() => setTime(new Date().toString()), 1000); return <p>{time}</p>; }
We just pass in the callback to run as the first argument and the interval as the second argument, like the setInterval
function.
It also comes with the useTimeout
Hook to run a callback after a given delay:
import React from "react"; import { useTimeout } from "react-hookedup"; export default function App() { useTimeout(() => alert("hello world"), 1500); return <h1>hello world</h1>; }
Another useful Hook from React hookedUp is useOnlineStatus
, which allows us to watch the online status of our app. For example, we can write:
import React from "react"; import { useOnlineStatus } from "react-hookedup"; export default function App() { const { online } = useOnlineStatus(); return <h1>{online ? "online" : "offline"}</h1>; }
It returns the online
property, which is true
when the device is online.
Like we mentioned earlier, React hookedUp also comes with the suite of state management Hooks that comes with the libraries we looked at earlier. These work similarly to how they work in the other libraries.
4. react-use
The react-use Hooks library comes with a larger collection of Hooks than the other libraries listed so far, including Hooks to leverage the various hardware that browsers can access. It also comes with Hooks to watch screen size, motion, scrolling, animation, and to dynamically adjust CSS, among many others.
For instance, we can use the useMouse
Hook to watch the position of a user’s mouse:
import React from "react"; import { useMouse } from "react-use"; export default function App() { const ref = React.useRef(null); const { docX, docY, posX, posY, elX, elY, elW, elH } = useMouse(ref); return ( <div ref={ref}> <div> Mouse position in document - ({docX}, {docY}) </div> <div> Mouse position in element - ({elX}, {elY}) </div> <div> Element position- ({posX} , {posY}) </div> <div> Element dimensions - {elW}x{elH} </div> </div> ); }
We can use the docX
and docY
to get the x- and y-coordinates of the mouse in the document. Also, we can use the elX
and elY
properties to get the x- and y-coordinates of the mouse in the element being monitored. We assign the ref to the element we want to watch.
More great articles from LogRocket:
- Don't miss a moment with The Replay, a curated newsletter from LogRocket
- Learn how LogRocket's Galileo cuts through the noise to proactively resolve issues in your app
- Use React's useEffect to optimize your application's performance
- Switch between multiple versions of Node
- Discover how to animate your React app with AnimXYZ
- Explore Tauri, a new framework for building binaries
- Advisory boards aren’t just for executives. Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.
Similarly, we can use the useScroll
Hook to track the scroll position of an element:
import React from "react"; import { useScroll } from "react-use"; export default function App() { const scrollRef = React.useRef(null); const { x, y } = useScroll(scrollRef); return ( <div ref={scrollRef} style={{ height: 300, overflowY: "scroll" }}> <div style={{ position: "fixed" }}> <div>x: {x}</div> <div>y: {y}</div> </div> {Array(100) .fill() .map((_, i) => ( <p key={i}>{i}</p> ))} </div> ); }
We assign a ref to the element whose scroll position we want to watch, and we set the height
and overflowY
to scroll
so that we can scroll the content. We get the scroll position with the x
and y
properties returned.
We can also use Hooks react-use provides for animation. For example, we can use the useSpring
Hook to animate number displays:
import React, { useState } from "react"; import useSpring from "react-use/lib/useSpring"; export default function App() { const [target, setTarget] = useState(50); const value = useSpring(target); return ( <div> {value} <br /> <button onClick={() => setTarget(0)}>Set 0</button> <button onClick={() => setTarget(200)}>Set 100</button> </div> ); }
We pass the number to animate to into the useSpring
Hook. Then the number will animate until the target
is reached. Note that the rebound
is required for this Hook to work.
The library also has Hooks to let us commit various side effects, like copying data to the clipboard and manipulating local storage. To add a copy-to-clipboard feature, we can use the useCopyToClipboard
Hook:
import React, { useState } from "react"; import useCopyToClipboard from "react-use/lib/useCopyToClipboard"; export default function App() { const [text, setText] = useState(""); const [state, copyToClipboard] = useCopyToClipboard(); return ( <div> <input value={text} onChange={(e) => setText(e.target.value)} /> <button type="button" onClick={() => copyToClipboard(text)}> copy text </button> {state.error ? ( <p>error: {state.error.message}</p> ) : ( state.value && <p>Copied {state.value}</p> )} </div> ); }
We just call useCopyToClipboard
in our component to get the copyToClipboard
function, then we can call that to copy whatever is passed in as the argument to the clipboard.
Likewise, we can easily work with local storage via the useLocalStorage
Hook:
import React from "react"; import useLocalStorage from "react-use/lib/useLocalStorage"; export default function App() { const [value, setValue, remove] = useLocalStorage("key", "foo"); return ( <div> <div>Value: {value}</div> <button onClick={() => setValue("bar")}>bar</button> <button onClick={() => setValue("baz")}>baz</button> <button onClick={() => remove()}>Remove</button> </div> ); }
value
has the value of the local storage entry with the given key, setValue
lets us pass in the value to set, and remove
removes the entry from local storage.
In addition to the aforementioned Hooks, which are unique to react-use, the library comes with many Hooks for setting states, using browser APIs, running async code, and much more. react-use is by far the most comprehensive Hooks library we’ve looked at so far.
5. React Recipes
React Recipes is another Hooks library that comes with many custom Hooks. It offers many of the same Hooks as react-use, such as Hooks that use browser APIs, manage states, run async code, etc.
For example, we can use the useSpeechSynthesis
Hook to make the browser speak:
import React, { useState } from "react"; import { useSpeechSynthesis } from "react-recipes"; export default function App() { const [value, setValue] = useState(""); const [ended, setEnded] = useState(false); const onBoundary = (event) => { console.log(`${event.name}: ${event.elapsedTime} milliseconds.`); }; const onEnd = () => setEnded(true); const onError = (event) => { console.warn(event); }; const { cancel, speak, speaking, supported, voices, pause, resume } = useSpeechSynthesis({ onEnd, onBoundary, onError }); if (!supported) { return "Speech is not supported."; } return ( <div> <input value={value} onChange={(event) => setValue(event.target.value)} /> <button type="button" onClick={() => speak({ text: value, voice: voices[1] })} > Speak </button> <button type="button" onClick={cancel}> Cancel </button> <button type="button" onClick={pause}> Pause </button> <button type="button" onClick={resume}> Resume </button> <p>{speaking && "Voice is speaking"}</p> <p>{ended && "Voice has ended"}</p> <div> <h2>Voices:</h2> <div> {voices.map((voice) => ( <p key={voice.name}>{voice.name}</p> ))} </div> </div> </div> ); }
We call the useSpeechSynthesis
Hook, which returns an object with various properties:
cancel
cancels the speech synthesisspeak
makes the browser start speakingspeaking
is a Boolean that tells us whether speech synthesis is in processsupported
is a Boolean that informs us whether speech synthesis is supported in the current browservoices
has the list of voices to choose frompause
lets us pause speakingresume
lets us resume speaking
It comes with many Hooks listed here, which provide us with lots of functionality that isn’t provided by React itself out of the box. It’s also worth nothing that it is a truly well-documented and comprehensive library.
The verdict?
By far the most comprehensive and useful React Hooks libraries we reviewed today are react-use and React Recipes. They provide us with lots of Hooks for a variety of use cases so that we don’t have to write them ourselves from scratch.
React Hooks Lib, react-hanger, and React hookedUp provide some basic Hooks for state management that can help us simplify state management to a certain extent. If that’s all we’re looking for out of a Hooks library, then React Hooks Lib, react-hanger, and React hookedUp are useful. They are all easy to use, and all of them (except React Hooks Lib) are clearly documented.
LogRocket: Full visibility into your production React apps
Debugging React applications can be difficult, especially when users experience issues that are hard to reproduce. If you’re interested in monitoring and tracking Redux state, automatically surfacing JavaScript errors, and tracking slow network requests and component load time, try LogRocket.

LogRocket combines session replay, product analytics, and error tracking – empowering software teams to create the ideal web and mobile product experience. What does that mean for you?
Instead of guessing why errors happen, or asking users for screenshots and log dumps, LogRocket lets you replay problems as if they happened in your own browser to quickly understand what went wrong.
No more noisy alerting. Smart error tracking lets you triage and categorize issues, then learns from this. Get notified of impactful user issues, not false positives. Less alerts, way more useful signal.
The LogRocket Redux middleware package adds an extra layer of visibility into your user sessions. LogRocket logs all actions and state from your Redux stores.
Modernize how you debug your React apps — start monitoring for free.