Hooks in React at a Glance
Hooks functions are a new adjunct in React that lets you manage state and other features without writing a class. These functions can only be used in function components, not in class components. It begins with the syntax “use”. Since hooks let us use functional components, it means there’s less code compared to class components. This makes our code more readable.
useState()
The most commonly used hook is— useState()
.
const [count, setCount] = useState();
Basically, this uses a destructuring assignment for arrays. The useState()
the function gives us 2 things:
count
: a value which will hold our state valuesetCount
: a function which will change ourcount
variable
import React, { useState } from 'react';
function Example() {
// Declare a new state variable, which we'll call "count" const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
Here, we’re using the setCount
function (remember we destructured/declared this from the useState()
hook) to change the count
variable.
After the button clicked, we update the count
variable by 1
. Since this is a change of state this triggers a rerender, and React updates the view with the new count
value for us.
useEffect()
The Effect Hook lets you perform data fetching, setting up a subscription, and manually changing the DOM in React components.
By using Effect Hook, we tell React that our component needs to do something after render. React will remember the function we passed and call it after executing the DOM. By using this effect, we can call some other imperative API.
import React, { useState, useEffect } from 'react';
function Example() {
const [count, setCount] = useState(0);
useEffect(() => { document.title = `You clicked ${count} times`; });
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
Here we declare the count
state variable, and then we tell React we need to use an effect. We pass a function to the useEffect
Hook. Inside our function, we set the document title using the document.title
browser API. When the component rendered, it will remember the effect we used, and then run the effect after updating the DOM.
useContext()
This hook mostly related to Context API. So we first need to have a good understanding of the Context API
useContext
lets you subscribe to React context without introducing nesting:
function Example() {
const locale = useContext(LocaleContext);
const theme = useContext(ThemeContext); // ...
}
useReducer()
useReducer
is another hook, convenient for dealing with more complex state changes in React components.
function Todos() {
const [todos, dispatch] = useReducer(todosReducer); // ...
There are some rarely used additional Hooks include: useCallback
, useMemo
, useRef
, useImperativeHandle
, useLayoutEffect
and useDebugValue
.
useCallback()
useCallback()
takes a function and a list of dependencies as arguments. It’s often is used in conjunction with useEffect()
.
useMemo()
useMemo
is similar to useCallback
except it allows you to apply memoization to any value type (not just functions).
useRef()
useRef
accepts an initial value as its first argument and it returns an object that has a current
property.
useImperativeHandle()
useImperativeHandle
lets you do two things:
- It gives you control over the value that is returned. Instead of returning the instance element, you explicitly state what the return value will be (see snippet below).
- It allows you to replace native functions (such as
blur
,focus
, etc) with functions of your own, thus allowing side-effects to the normal behavior or a different behavior altogether. Though, you can call the function whatever you like.
useLayoutEffect()
useLayoutEffect
hook is similar to the useEffect
hook. It takes a function called effect
as its first argument and an array of dependencies as the second argument. The first argument, effect
either returns a cleanup
function or undefined
. The function signature is illustrated in the code below.
import React, { useLayoutEffect } from "react";
const APP = props => {
useLayoutEffect(() => {
//Do something and either return undefined or a cleanup function
return () => {
//Do some cleanup here
};
}, [dependencies]);
};
useDebugValue()
Sometimes you might want to debug certain values or properties, but doing so might require expensive operations that might impact performance.
useDebugValue
is only called when the React DevTools is open and the related hook is inspected, preventing any impact on performance.