A Guide to Essential React Hooks useState, useEffect, and useRef
React’s hooks API allows functional components to manage state, handle side effects, and interact with the DOM more effectively. Three of the most commonly used hooks useState
, useEffect
, and useRef
are essential tools in any React developer’s toolkit. In this guide, we will explore each of these hooks, explaining how they work and providing examples to demonstrate their practical use.
1. useState
: Managing component state
useState
lets you add and manage state within functional components. Instead of defining state in a class, useState
provides a simpler way to declare state variables directly within the component function.
Basic syntax
import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}
In this example, count
is a state variable initialized to 0
, and setCount
is a function to update count
. Each button click increments the count, causing the component to re-render with the updated value.
2. useEffect
: Handling side effects
useEffect
is useful for managing side effects like data fetching, manual DOM manipulation, or setting up subscriptions. It runs after the component renders and whenever its dependencies change.
Basic syntax
import React, { useState, useEffect } from 'react';
function Timer() {
const [seconds, setSeconds] = useState(0);
useEffect(() => {
const interval = setInterval(() => {
setSeconds((prev) => prev + 1);
}, 1000);
return () => clearInterval(interval);
}, []); // Empty array to run effect only on mount
return <p>Timer: {seconds} seconds</p>;
}
Here, useEffect
sets up an interval timer when the component mounts and cleans it up when the component unmounts. The empty array as the second argument ensures the effect runs only once on mount.
3. useRef
: Accessing DOM elements and persisting value
useRef
creates a reference to DOM elements or mutable values that persist across renders. It doesn’t trigger re-renders, making it ideal for cases like managing focus, holding mutable values, or integrating with third-party libraries.
Basic syntax
import React, { useRef } from 'react';
function TextInputFocus() {
const inputRef = useRef(null);
const focusInput = () => {
inputRef.current.focus();
};
return (
<div>
<input ref={inputRef} type="text" placeholder="Click button to focus" />
<button onClick={focusInput}>Focus Input</button>
</div>
);
}
In this example, inputRef
stores a reference to the input element, allowing us to focus it directly with the focusInput
function.
Practical use cases for each hook:
useState
: Managing state at component level.useEffect
: Managing side effects like fetching data, adding subscriptions and event listeners.useRef
: Storing references to DOM elements or values across renders without trigerring re-renders.