Sitemap
5 min readApr 18, 2025

--

Press enter or click to view image in full size

React Hooks

React Hooks are functions that let you “hook into” React state and lifecycle features from function components. Before Hooks, these features were only available in class components. Now, with Hooks, function components can do everything class components can — with cleaner, more modular, and reusable code.

🪝 What are React Hooks?

Hooks are special functions that let you manage state, side effects, context, refs, and more inside function components — without using classes.

They were introduced in React 16.8 to make components simpler and more powerful.

🧠 Why use Hooks?

  • Simplify code by using functions instead of classes.
  • Reuse logic across components using custom hooks.
  • Reduce boilerplate and lifecycle complexity (like componentDidMount, componentDidUpdate, etc.).
  • Improve separation of concerns, as logic can be split into smaller, focused hooks.

✅ Rules of Hooks

  • Only call hooks at the top level (not inside loops, conditions, or nested functions).
  • Only call hooks from React functions (components or custom hooks).

🧠 What is useState?

useState is a React Hook that lets you add state to a functional component.

🔧 Syntax:

const [state, setState] = useState(initialValue);

Example: A Counter App

import React, { useState } from 'react';

function Counter() {
const [count, setCount] = useState(0);

const increment = () => setCount(count + 1);
const decrement = () => setCount(count - 1);
const reset = () => setCount(0);

return (
<div style={{ textAlign: 'center', marginTop: '2rem' }}>
<h2> Counter: {count}</h2>
<button onClick={increment}>➕ Increment</button>
<button onClick={decrement}>➖ Decrement</button>
<button onClick={reset}> Reset</button>
</div>
);
}

export default Counter;

📝 React Form Example using useState

import React, { useState } from 'react';

function ContactForm() {
const [formData, setFormData] = useState({
name: '',
email: '',
});

const handleChange = (e) => {
const { name, value } = e.target;

setFormData((prevData) => ({
...prevData,
[name]: value,
}));
};

const handleSubmit = (e) => {
e.preventDefault();
alert(`Submitted:\nName: ${formData.name}\nEmail: ${formData.email}`);
// Optionally reset form
setFormData({ name: '', email: '' });
};

return (
<form onSubmit={handleSubmit} style={{ maxWidth: '400px', margin: 'auto' }}>
<h2>📬 Contact Form</h2>
<div>
<label>Name:</label><br />
<input
type="text"
name="name"
value={formData.name}
onChange={handleChange}
placeholder="Your name"
/>
</div>
<br />
<div>
<label>Email:</label><br />
<input
type="email"
name="email"
value={formData.email}
onChange={handleChange}
placeholder="you@example.com"
/>
</div>
<br />
<button type="submit">Submit</button>
</form>
);
}

export default ContactForm;

🧠 What is useEffect?

useEffect is a React Hook that lets you run side effects in function components—like fetching data, updating the DOM, setting up subscriptions, timers, and more. useEffect accepts two arguments. The second argument is optional.

🔧 Syntax:

useEffect(() => {
// side effect logic here

return () => {
// cleanup logic here (optional)
};
}, [dependencies]);

🧼 Example: Cleanup (Component Unmount)

useEffect(() => {
const timer = setInterval(() => console.log('Tick'), 1000);

return () => clearInterval(timer); // cleanup on unmount
}, []);

🧠 What is useContext?

useContext is a React Hook that lets you read values from a Context directly inside any function component — without needing to pass props manually through every level of the component tree.

Get Rijan’s stories in your inbox

Join Medium for free to get updates from this writer.

It’s often used for:

  • Themes (light/dark)
  • User authentication info
  • App settings
  • Language/locale settings
  • Shared data between deeply nested components

🧪 Syntax:

const value = useContext(MyContext);
  • MyContext is the context object created using React.createContext().
  • value is the current value stored in the context, provided by a <MyContext.Provider> somewhere higher in the component tree.

✅ Step-by-Step Example

  1. Create the Context
import React, { createContext } from 'react';

export const ThemeContext = createContext();

2. Provide the Context (usually near App root)

import React, { useState } from 'react';
import { ThemeContext } from './ThemeContext';
import ChildComponent from './ChildComponent';

function App() {
const [darkMode, setDarkMode] = useState(false);

return (
<ThemeContext.Provider value={{ darkMode, setDarkMode }}>
<ChildComponent />
</ThemeContext.Provider>
);
}

3. Consume the Context Anywhere with useContext

import React, { useContext } from 'react';
import { ThemeContext } from './ThemeContext';

function ChildComponent() {
const { darkMode, setDarkMode } = useContext(ThemeContext);

return (
<div>
<p>Theme: {darkMode ? '🌙 Dark' : '☀️ Light'}</p>
<button onClick={() => setDarkMode(!darkMode)}>
Toggle Theme
</button>
</div>
);
}

⚠️ Important Notes:

  • Context is global to the part of the component tree wrapped in a Provider.
  • Changing context values causes all consuming components to re-render.
  • Use carefully to avoid unnecessary re-renders in large apps.

4. File Structure

/src
/ThemeContext.js // Where we create the context
/App.js // Main app that provides the context
/ChildComponent.js // Component that consumes the context

🧠 What is useMemo?
useMemo memoizes the result of a computation and only re-computes it when one of its dependencies has changed. This is especially useful when you have complex calculations or heavy computations that should not be repeated on every render unless absolutely necessary.

🧪 Syntax:

const memoizedValue = useMemo(() => {
// Expensive computation or logic
return computedValue;
}, [dependencies]);
  • memoizedValue: This is the result of your computation, memoized so it only recalculates when dependencies change.
  • dependencies: The array of values that the memoized function depends on. If any value in the array changes, React will recompute the value.

✅ When to Use useMemo:

  • Expensive calculations that do not need to run on every render.
  • Optimizing rendering performance of complex components by preventing unnecessary recalculations.
  • Handling large data processing (e.g., filtering, sorting) that doesn’t need to run unless the data or conditions change.

🔄 Example

Let’s say we have a list of numbers and need to compute the sum of those numbers, which can be expensive for large arrays. We can use useMemo to optimize the computation.

import React, { useState, useMemo } from 'react';

function ExpensiveCalculation() {
const [count, setCount] = useState(0);
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

// Use useMemo to only re-calculate when `numbers` change
const sum = useMemo(() => {
console.log("Calculating sum...");
return numbers.reduce((acc, num) => acc + num, 0);
}, [numbers]); // Recalculate only when `numbers` changes

return (
<div>
<p>Sum of numbers: {sum}</p>
<button onClick={() => setCount(count + 1)}>Increment Count</button>
<p>Count: {count}</p>
</div>
);
}

export default ExpensiveCalculation;

📌 Key Points:

  • The sum of numbers will only be recalculated when numbers change, not when count changes (since count is not in the dependency array).
  • Without useMemo, the sum would be recalculated on every render, even when it hasn't changed.
  • The console log Calculating sum... will only appear when the sum actually recalculates, showing the effect of memoization.

✅ Conclusion: Mastering Core React Hooks

React’s core hooks — useState, useEffect, useContext, and useMemo—empower developers to write cleaner, more efficient, and scalable components using functional patterns. useState enables local state management, useEffect handles side effects with fine control via the dependency array, useContext simplifies global state sharing without prop drilling, and useMemo optimizes performance by memoizing expensive computations. Together, these hooks form the backbone of modern React development, allowing for cleaner code, better performance, and more maintainable applications.

--

--