React Hooks 101 & Beyond: How to Build Your Own Hooks

React is one of the most popular JavaScript libraries for building user interfaces. Before 2018, React components were divided into two camps: class components (which could hold state and lifecycle methods) and functional components (which couldn’t).
Hooks changed everything.
Introduced in React 16.8, Hooks let you use state and other React features inside functional components—without writing a class.
What Are Hooks?
Hooks are not more than just JavaScript functions that let you “hook into” React features like state, lifecycle, and context.
They look like regular functions, but they follow special rules and naming conventions (e.g., their names start with use
as per convention).
Let’s walk through the most commonly used hooks and see how they work.
1.) useState
: Manage Component State
Definition:useState
lets you add state (data that changes over time) to functional components.
How it works:
You call
useState
inside your component to create a state variable.React preserves this state between re-renders.
When you update state, React re-renders the component.
Where it’s mainly used:
Handling form inputs
Toggling UI (like modals or dropdowns)
Storing fetched data
Syntax:
const [state, setState] = useState(initialValue);
//here state is the value
//setState is function that will store value in state
Example:
import { useState } from "react";
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}
Every time you click the button, count
increases and the component re-renders.
2.) useEffect
: Side Effects and Lifecycle
Definition:useEffect
lets you perform side effects in your component—like fetching data, updating the DOM, or subscribing to events.
How it works:
useEffect
runs after every render by default.You can control when it runs by passing a dependency array.
It can also return a cleanup function to run when the component unmounts or dependencies change.
Where it’s mainly used:
Data fetching on mount
Listening to window events
Subscribing/unsubscribing to external services
Syntax:
useEffect(() => {
// code to run on mount/update
return () => {
// cleanup
};
}, [dependencies]);
Example:
import { useEffect, useState } from "react";
function Timer() {
const [count, setCount] = useState(0);
useEffect(() => {
const interval = setInterval(() => {
setCount(c => c + 1);
}, 1000);
return () => clearInterval(interval);
}, []);
return <p>Timer: {count}</p>;
}
This sets up a timer when the component mounts and cleans it up when it unmounts.
3.) useRef
: Mutable References
Definition:useRef
lets you persist a mutable value that doesn’t trigger a re-render when it changes.
How it works:
Returns an object with a
.current
property.Updating
.current
does not cause the component to re-render.Commonly used to access DOM nodes or store mutable values.
Where it’s mainly used:
Accessing DOM elements (like input focus)
Storing timers or intervals
Keeping a mutable value across renders without causing re-render
Syntax:
const myRef = useRef(initialValue);
Example:
import { useRef, useEffect } from "react";
function InputFocus() {
const inputRef = useRef(null);
useEffect(() => {
inputRef.current.focus();
}, []);
return <input ref={inputRef} placeholder="I will be focused" />;
}
//Try this out
Note: Updating useRef
doesn’t trigger a re-render, while updating useState
does.
4.) useContext
: Share State Globally
Definition:useContext
lets you read and subscribe to context (shared state) in your component without passing props manually at every level.
How it works:
You create a context with
React.createContext
.Use a
Provider
to pass the context value.useContext
consumes the value anywhere in the component tree.
Where it’s mainly used:
Global themes or user data
Authentication status
Multi-language (i18n) support
Syntax:
const value = useContext(MyContext);
Example:
import { createContext, useContext } from "react";
const ThemeContext = createContext("light");
function ThemedButton() {
const theme = useContext(ThemeContext);
return <button>{theme === "dark" ? "Dark Mode" : "Light Mode"}</button>;
}
function App() {
return (
<ThemeContext.Provider value="dark">
<ThemedButton />
</ThemeContext.Provider>
);
}
The button will show Dark Mode because it reads the context value.
Note on useMemo
and useCallback
useMemo
and useCallback
are used to memoize values and functions to avoid unnecessary re-computations or re-creations between renders. However, starting React 19, their usage is significantly reduced because React’s compiler can optimize re-renders more intelligently.
In most cases, you may no longer need to wrap everything in useMemo
or useCallback
—focus on real performance bottlenecks instead.
While developing in React, you’ll find yourself mostly juggling between useState
and useEffect
, as these two hooks cover the majority of day-to-day component logic. If you’d like to explore more advanced hooks, you can always refer to the official React documentation for a completet list and detailed usage examples.
How to Create a Custom Hook
Custom hooks are just functions that start with use
and can call other hooks internally. They help you encapsulate and reuse logic.
Example:
import { useState, useEffect } from "react";
function useFetch(url) {
const [data, setData] = useState(null);
useEffect(() => {
fetch(url)
.then(res => res.json())
.then(setData);
}, [url]);
return data;
}
Usage:
function Posts() {
const posts = useFetch("https://website.com/value");
if (!posts) return <p>Loading...</p>;
return (
<ul>
{posts.map(post => (
<li key={post.id}>{post.title}</li>
))}
</ul>
);
}
Custom hooks make your components cleaner and easier to maintain.
TL;DR
React Hooks have transformed how developers write components, bringing state, side effects, and shared logic into functional components in a simple, elegant way. Whether you’re managing state with useState
, performing side effects with useEffect
, or encapsulating logic with custom hooks, mastering Hooks is essential for modern React development.
Subscribe to my newsletter
Read articles from VANSH KANSAL directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
