React 16.8 shipped with Hooks, and they’ve changed how I write React components. No more class components for simple state management. Here’s my introduction to the two most important hooks.
The Problem with Classes
Class components work, but they’re verbose. You need constructors, binding methods, lifecycle methods spread across the component. Hooks let you use state and effects in function components.
useState
The simplest hook. It returns a value and a setter:
import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>+</button>
<button onClick={() => setCount(count - 1)}>-</button>
<button onClick={() => setCount(0)}>Reset</button>
</div>
);
}
You can have multiple state variables:
function Form() {
const [name, setName] = useState('');
const [email, setEmail] = useState('');
const [isSubmitting, setIsSubmitting] = useState(false);
// Or use an object
const [form, setForm] = useState({ name: '', email: '' });
}
useEffect
useEffect is for side effects: data fetching, subscriptions, DOM manipulation. It runs after render:
import React, { useState, useEffect } from 'react';
function UserProfile({ userId }) {
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
async function fetchUser() {
setLoading(true);
const response = await fetch(`/api/users/${userId}`);
const data = await response.json();
setUser(data);
setLoading(false);
}
fetchUser();
}, [userId]); // Re-run when userId changes
if (loading) return <div>Loading...</div>;
return <div>Hello, {user.name}</div>;
}
The Dependency Array
The second argument to useEffect controls when it runs:
// Runs after every render
useEffect(() => { ... });
// Runs once on mount
useEffect(() => { ... }, []);
// Runs when dependencies change
useEffect(() => { ... }, [userId, something]);
Cleanup
Return a function from useEffect for cleanup:
useEffect(() => {
const subscription = dataSource.subscribe(handleData);
return () => {
subscription.unsubscribe();
};
}, [dataSource]);
Rules of Hooks
- Only call hooks at the top level (not in loops or conditions)
- Only call hooks from React functions
- Name custom hooks starting with “use”
References
Discover more from C4: Container, Code, Cloud & Context
Subscribe to get the latest posts sent to your email.