React Hooks are somewhat a new addition to React. They allow you to use React features without the need to use a class. But I am not going to go through an introduction in this post, there are many great intro posts out there. This post shows you a few nifty hooks and what you can achieve with them.
react-use-form-state
hook
Forms are a very common pattern when it comes to getting information from users. From small to large forms, they all have their own state we have to manage, whether it's for validation or to populate another input based on previous selection.
This hook is a handy tool which allows you simplify managing form's state using the native HTML input fields.
You can install it with:
npm i react-use-form-state
And a simple usage:
import { useFormState } from 'react-use-form-state';
export default function SignUpForm({ onSubmit }) {
const [formState, { text, email, password, radio }] = useFormState();
function handleSubmit(e) {
// ...
}
return (
<form onSubmit={handleSubmit}>
<input {...text('name')} />
<input {...email('email')} required />
<input {...password('password')} required minLength="8" />
<input {...radio('plan', 'free')} />
<input {...radio('plan', 'premium')} />
</form>
);
}
With this you get a json
structure like this:
{
values: {
name: 'Mary Poppins',
email: 'mary@example.com',
password: '1234',
plan: 'free',
},
touched: {
name: true,
email: true,
password: true,
plan: true,
},
validity: {
name: true,
email: true,
password: false,
plan: true,
},
errors: {
password: 'Please lengthen this text to 8 characters or more',
},
clear: Function,
clearField: Function,
reset: Function,
resetField: Function,
setField: Function,
}
It also allow you to initialise it via initialState
object, a wide variety of on form event handlers, advanced input options, custom input validation, custom controls and much more. Definitely check their GitHub Repo for more information.
wsmd / react-use-form-state
π React hook for managing forms and inputs state
use-media
This tiny hook is really handy if you're trying to deliver a responsive user experience. It tracks the state of a CSS media query and lets you act on that.
With useEffect
:
import useMedia from 'use-media';
// Alternatively, you can import as:
// import {useMedia} from 'use-media';
const Demo = () => {
// Accepts an object of features to test
const isWide = useMedia({minWidth: 1000});
// Or a regular media query string
const reduceMotion = useMedia('(prefers-reduced-motion: reduce)');
return (
<div>
Screen is wide: {isWide ? 'π' : 'π’'}
</div>
);
};
With useLayoutEffect
:
import {useMediaLayout} from 'use-media';
const Demo = () => {
// Accepts an object of features to test
const isWide = useMediaLayout({minWidth: 1000});
// Or a regular media query string
const reduceMotion = useMediaLayout('(prefers-reduced-motion: reduce)');
return (
<div>
Screen is wide: {isWide ? 'π' : 'π’'}
</div>
);
};
For more information about this nifty little hook, visit this GitHub repo.
react-firebase-hooks
I don't have to tell you how great firebase is, but what if you could use a set of hooks to easily integrate with it? It's got 4 set of hooks for you to use:
Usage:
import { useAuthState } from 'react-firebase-hooks/auth';
const CurrentUser = () => {
const [user, initialising, error] = useAuthState(firebase.auth());
const login = () => {
firebase.auth().signInWithEmailAndPassword('test@test.com', 'password');
};
const logout = () => {
firebase.auth().signOut();
};
if (initialising) {
return (
<div>
<p>Initialising User...</p>
</div>
);
}
if (error) {
return (
<div>
<p>Error: {error}</p>
</div>
);
}
if (user) {
return (
<div>
<p>Current User: {user.email}</p>
<button onClick={logout}>Log out</button>
</div>
);
}
return <button onClick={login}>Log in</button>;
};
Of course you don't hard code your username and password right? π
Find out more here.
CSFrequency / react-firebase-hooks
React Hooks for Firebase.
use-onClickOutside
hook
Many times has happened for me to need to be aware of when the user clicks outside of an element. This might be to change something or perform an action. This little hook allows you to do exactly that:
import * as React from 'react'
import useOnClickOutside from 'use-onclickoutside'
export default function Modal({ close }) {
const ref = React.useRef(null)
useOnClickOutside(ref, close)
return <div ref={ref}>{'Modal content'}</div>
}
As you can see, you can provide a ref to an element and pass it to the hook. If there is a click anywhere outside of the element, the the call-back function, in this case close
is called.
Find out more about this hook in this GitHub repo.
Andarist / use-onclickoutside
React hook for listening for clicks outside of an element.
useIntersectionObserver
hook
You might remember I did a post on image optimisation and how IntersectionObserver
API is a handy tool to load an image lazily when it appears on viewport.
This hook allows you to use this great API:
import React, { useRef, useState } from "react";
import { useIntersectionObserver } from "react-hook-intersection-observer";
const App = () => {
const root = useRef(); // We need a ref to our "root" or our parent,
const target = useRef(); // We need a ref to our "target" or our child-to-watch,
// Let's use a bit of state.
const [isThingIntersecting, setThingIntersecting] = useState(false);
// Here's our hook! Let's give it some configuration...
useIntersectionObserver({
root,
target,
// What do we do when it intersects?
// The signature of this callback is (collectionOfIntersections, observerElement).
onIntersect: ([{ isIntersecting }]) => setThingIntersecting(isIntersecting)
});
return (
<div className="App">
<h1>useIntersectionObserver</h1>
<h2>
The thing is currently{" "}
{!isThingIntersecting && <span style={{ color: "red" }}>not</span>}{" "}
<span style={{ color: isThingIntersecting ? "green" : "black" }}>
intersecting
</span>
!
</h2>
<div ref={root} className="black-box">
<div className="larger-box">
<div ref={target}>THE THING</div>
</div>
</div>
</div>
);
};
To find out more, have a look at this GitHub repo.
TejasQ / react-hook-intersection-observer
A simple React hook that works with the Intersection Observer API.
react-use
collection
This is a collection of some great hooks you can use in categories like Sensors, UI, Animations, Side-effects, Lifecycles, and State.
An example is useLocation
which gives you the ability to access the location of the browser.
import {useLocation} from 'react-use';
const Demo = () => {
const state = useLocation();
return (
<pre>
{JSON.stringify(state, null, 2)}
</pre>
);
};
If you're using Internet Explorer (but why π), you can use this polyfill.
Or you can use useBattery
to track the battery status on a mobile device:
import {useBattery} from 'react-use';
const Demo = () => {
const batteryState = useBattery();
if (!batteryState.isSupported) {
return (
<div>
<strong>Battery sensor</strong>: <span>not supported</span>
</div>
);
}
if (!batteryState.fetched) {
return (
<div>
<strong>Battery sensor</strong>: <span>supported</span> <br />
<strong>Battery state</strong>: <span>fetching</span>
</div>
);
}
return (
<div>
<strong>Battery sensor</strong>: <span>supported</span> <br />
<strong>Battery state</strong>: <span>fetched</span> <br />
<strong>Charge level</strong>: <span>{ (batteryState.level * 100).toFixed(0) }%</span> <br />
<strong>Charging</strong>: <span>{ batteryState.charging ? 'yes' : 'no' }</span> <br />
<strong>Charging time</strong>:
<span>{ batteryState.chargingTime ? batteryState.chargingTime : 'finished' }</span> <br />
<strong>Discharging time</strong>: <span>{ batteryState.dischargingTime }</span>
</div>
);
};
To find out about all of those, check this GitHub repo.
React Redux hooks
React Redux now offers a set of hook APIs as an alternative to the existing connect()
Higher Order Component. These APIs allow you to subscribe to the Redux store and dispatch actions, without having to wrap your components in connect()
.
Here is the useSelector
hook returns a part of all of store using a selector function.
import React from 'react'
import { useSelector } from 'react-redux'
export const CounterComponent = () => {
const counter = useSelector(state => state.counter)
return <div>{counter}</div>
}
Checkout their comprehensive documentation to find out more.
react-hanger
A set of helpful hooks with focus on primitive types state changing. They have two version, but the recommendation is to use V2.
Install:
yarn add react-hanger
Usage:
import React, { Component } from "react";
import {
useInput,
useBoolean,
useNumber,
useArray,
useOnMount,
useOnUnmount
} from "react-hanger";
const App = () => {
const newTodo = useInput("");
const showCounter = useBoolean(true);
const limitedNumber = useNumber(3, { lowerLimit: 0, upperLimit: 5 });
const counter = useNumber(0);
const todos = useArray(["hi there", "sup", "world"]);
const rotatingNumber = useNumber(0, {
lowerLimit: 0,
upperLimit: 4,
loop: true
});
return (
<div>
<button onClick={showCounter.toggle}> toggle counter </button>
<button onClick={() => counter.increase()}> increase </button>
{showCounter.value && <span> {counter.value} </span>}
<button onClick={() => counter.decrease()}> decrease </button>
<button onClick={todos.clear}> clear todos </button>
<input type="text" value={newTodo.value} onChange={newTodo.onChange} />
</div>
);
};
You can play with these in this CodeSandbox.
Check this GitHub repo for more information.
kitze / react-hanger
A collection of useful React hooks
Summary
I was surprised to find out how many hooks have already being developed by the community to be honest. There are so many and I can't go through all of them here. But if you're hungry for more, check this gem I found which has a collection of tools, hooks, tutorials, videos, podcasts, and more.
rehooks / awesome-react-hooks
Awesome React Hooks
awesome-react-hooks
Awesome React Hooks Resources
Documentation
Discussions
Tutorials
- "Making Sense of React Hooks" by Dan Abramov
- "From React.Component to hooks" by Octave Raimbault
- "React Hooks: Whatβs going to happen to my tests?" by Kent C. Dodds
- "State Management with React Hooks - No Redux or Context API" by AndrΓ© Gardi
- "How to Fetch Data with React Hooks?" by Robin Wieruch
- Primer on React Hooks
- React Hooks - A deeper dive featuring useContext and useReducer
- "Using Custom React Hooks to Simplify Forms" by James King
- Testing of a Custom React Hook for Fetching Data with Axios
- The Guide to Learning React Hooks (Examples & Tutorials) by Eric Bishard
- "Sanely Testing React Hooks" by Dave Cooper
- React by Example: Hooks
Videos
-
π¬ ReactConf 2018: React Today and Tomorrow by Sophie Alpert and Dan Abramov Official announcement and first demo. -
π¬ ReactConf 2018: 90% Cleaner React byβ¦
Top comments (7)
Just great! this article is a very useful resource.
Very nice article, thanks! Definitely going into my list!
Thanks for this great list, I'm getting started with the hooks and some of those ones will definitely come in handy !
Really enjoyed this article. Thank you Yaser! Stoked to see a familiar name popping up on my feed ;)
Thanks mate
Thanks Yaser! This is a great list and appreciate you linking the source material!
Cheers!
Youβre welcome