Custom Hooks
Create reusable custom hooks to share stateful logic between components. This is a foundational concept in component-based UI development that professional developers rely on daily. The explanations below are written to be beginner-friendly while covering the depth and nuance that comes from real-world React experience. Take your time with each section and practice the examples
What are Custom Hooks?
Custom hooks are JavaScript functions that start with 'use' and may call other hooks. They allow you to extract component logic into reusable functions.. This is an essential concept that every React developer must understand thoroughly. In professional development environments, getting this right can mean the difference between code that works reliably and code that breaks in production. The following sections break this down into clear, digestible pieces with practical examples you can try immediately
Basic Custom Hook
// Custom hook for form input
function useInput(initialValue) {
const [value, setValue] = useState(initialValue);
const handleChange = (e) => {
setValue(e.target.value);
};
const reset = () => {
setValue(initialValue);
};
return [value, handleChange, reset];
}
// Using the custom hook
function LoginForm() {
const [username, handleUsernameChange, resetUsername] = useInput('');
const [password, handlePasswordChange, resetPassword] = useInput('');
const handleSubmit = (e) => {
e.preventDefault();
resetUsername();
resetPassword();
};
return (
<form onSubmit={handleSubmit}>
<input
type="text"
value={username}
onChange={handleUsernameChange}
placeholder="Username"
/>
<input
type="password"
value={password}
onChange={handlePasswordChange}
placeholder="Password"
/>
<button type="submit">Login</button>
</form>
);
}Advanced Custom Hook
// Custom hook for API calls
function useApi(url) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
const fetchData = async () => {
try {
setLoading(true);
setError(null);
const response = await fetch(url);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const result = await response.json();
setData(result);
} catch (err) {
setError(err.message);
} finally {
setLoading(false);
}
};
fetchData();
}, [url]);
return { data, loading, error };
}
// Using the custom hook
function UserList() {
const { data: users, loading, error } = useApi('/api/users');
if (loading) return <div>Loading users...</div>;
if (error) return <div>Error: {error}</div>;
if (!users) return <div>No users found</div>;
return (
<div>
<h1>Users</h1>
<ul>
{users.map(user => (
<li key={user.id}>{user.name}</li>
))}
</ul>
</div>
);
}