In this article we will see about react hooks and their usage. Before starting I assume you have decent knowledge of react and this post will help you to polish your information about react hooks so let’s begin.
Introduction.
In React.js v-0.14 the functional component was introduced. Before this only class components were in used and functional component was stateless. Later in React v-16.8 they introduced hooks for functional component for managing state. Initially hooks like useState and useEffect was in use but letter they introduced lots of useful hooks for simplifying UI development.
What are hooks in react.js?
In class component we were using setState to mange the state. Similarly in functional component we use hooks to for managing the state with many other advantages. It allows functional component to have access to the state and other react features. Due to this rich features of functional component the class components are no longer needed.
Creating custom hook is also possible. Hook is just JavaScript function which takes inputs and gives output accordingly. For ex. We have built-in hooks like useState and useEffect similar we can create another custom hooks like useWindowSize, useFetch, useDebounce, useLocalStorage etc.
useState and useEffect are mostly used hooks and I think you already have enough ideas about its usage. Let’s see the other types of React hooks that you can use in your project effectively.
1. useMemo
React hook useMemo memoizes or cache the result of calculation between re-renders. So it will only rerun if there is change in give dependency.
Usage -
1. Prevent unnecessary re-renders
2. Caches the result and skips expensive recalculation
const memoizedSum = useMemo(() => {
return sum(a, b);
}, [a, b]);
Here in this example , The function will calculate the sum only if there is change in a or b otherwise it will directly execute the same result of sum.
FYI - In React component when you set any state or there is change happening in values then re-renders will happen for another functions also(in same component. While child component will not be affected until its props changed ). Resulting unnecessary things will also run and will cause performance issue. So useMemo will help you to stop unnecessary re-renders and improve the performance of your site .
function MyComponent() {
const [count, setCount] = useState(0);
function sayHello() {
console.log('hello');
}
console.log('Component rendered');
return (
<div>
<button onClick={sayHello}>Say Hello</button>
…
</div>
);
}
Here when state change all function inside it will re-render which is unnecessary and cause performance issue.
function MyComponent() {
const [count, setCount] = useState(0);
const [other, setOther] = useState(0);
const sumValues = useMemo(() => {
console.log('Calculating...');
let total = 0;
for (let i = 0; i < 100000000; i++) {
total += count;
}
return total;
}, [count]);
return (
<div>
<button onClick={() => setCount(count + 1)}>Increase Count</button>
<button onClick={() => setOther(other + 1)}>Change Other</button>
<p>Expensive: {expensiveValue}</p>
</div>
);
}
Here all the function will re execute but because of memo sumValues will only recalculate if count changes.
2. useCallback.
useCallback hook lets you memoize the function definition so that it will render the function only if the dependency changes. Simply it cached the function.
Benefits:
1. Avoid unnecessary re-render especially when function passes to the child component.
2. You can update state from memoized callback
3. React will not call function itself. You will decide when and whether to call the function by considering its dependencies.
const handleSubmit = useCallback( (orderDetails) => {
post('/product/' + productId + '/buy', {
referrer,
orderDetails,
});
},
[productId, referrer]
);
In this code :
useCallback memoizes the handleSubmit
It only changes if productId or referrer changes.
Avoids recreating handleSubmit on every render
3. useRef
useRef is one of the important hook in React UI development. It has following features
1. It create mutable reference that persist the value across the render
2. It is also use to access all the properties of DOM element.
3. Does not trigger re-render when its value changes.
Main purpose - It does not cause DOM re-render or refresh. It’s just change .current value quietly. Perfect for keeping data without triggering UI updates.
import { useRef } from 'react';
function MyComponent() {
const inputRef = useRef(null);
useEffect(() => {
inputRef.current.focus(); // focuses the input on mount
}, []);
return <input ref={inputRef} />;
}
useRef returns only one item. And .”current” is its property to access values of DOM element in form of object.
const myRef = useRef();
{ current: ... }
Note: Do not use ref.current during rendering except initializing. It will cause unpredictable behavior of component.