In React, hooks are functions that let you "hook into" React state and lifecycle features from function components. Custom hooks are a powerful feature that allows you to extract component logic into reusable functions. This tutorial will walk you through the process of creating custom hooks in React.js, providing real-world examples and best practices.
A custom hook is a JavaScript function whose name starts with use and that may call other hooks. The purpose of a custom hook is to encapsulate and reuse logic across different components. By using custom hooks, you can write more readable and maintainable code.
Let's start by creating a simple custom hook that manages form input state and validation.
useFormInputimport { useState } from 'react';
function useFormInput(initialValue) {
const [value, setValue] = useState(initialValue);
function handleChange(e) {
setValue(e.target.value);
}
return {
value,
onChange: handleChange,
};
}
useState hook to initialize the input's state with the provided initialValue.handleChange function updates the state whenever the input changes.import React from 'react';
import useFormInput from './useFormInput';
function SignupForm() {
const email = useFormInput('');
const password = useFormInput('');
function handleSubmit(e) {
e.preventDefault();
console.log('Email:', email.value);
console.log('Password:', password.value);
}
return (
<form onSubmit={handleSubmit}>
<div>
<label>Email:</label>
<input type="email" {...email} />
</div>
<div>
<label>Password:</label>
<input type="password" {...password} />
</div>
<button type="submit">Sign Up</button>
</form>
);
}
export default SignupForm;
useFormInput custom hook.useFetchLet's create a more advanced custom hook that fetches data from an API.
useFetchimport { useState, useEffect } from 'react';
function useFetch(url) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
async function fetchData() {
try {
const response = await fetch(url);
if (!response.ok) {
throw new Error('Network response was not ok');
}
const json = await response.json();
setData(json);
} catch (err) {
setError(err.message);
} finally {
setLoading(false);
}
}
fetchData();
}, [url]);
return { data, loading, error };
}
useState to manage the fetched data, loading status, and any errors.useEffect hook is used to fetch data from the provided URL when the component mounts or the URL changes.import React from 'react';
import useFetch from './useFetch';
function UserList() {
const { data: users, loading, error } = useFetch('https://api.example.com/users');
if (loading) return <p>Loading...</p>;
if (error) return <p>Error: {error}</p>;
return (
<ul>
{users.map(user => (
<li key={user.id}>{user.name}</li>
))}
</ul>
);
}
export default UserList;
useFetch custom hook.use to make them recognizable as hooks.useEffect.Custom hooks in React.js provide a powerful way to encapsulate and reuse logic across components. By following the best practices outlined in this tutorial, you can create maintainable and reusable custom hooks that enhance the readability and functionality of your React applications.