Building Custom Hooks Library in React
Custom hooks in React allow developers to encapsulate and reuse logic, making it easier to manage state and side effects across multiple components. As applications become complex, developers often repeat similar patterns for state management, API calls, or event handling.
This can lead to code duplication and decreased maintainability. Building a Custom Hooks Library in React can solve these problems, providing a reusable, organized collection of hooks that improve consistency, performance, and code readability.
What is a Custom Hook Library?
A Custom Hook Library is a collection of reusable, encapsulated logic functions in React, known as custom hooks, that can be shared and used across multiple components and projects. A custom hook library acts as a centralized repository where these custom hooks are organized, making them easy to reuse in different parts of an application or even across different projects.
- Reusability: Across multiple components, hooks can be reused.
- Optimized Performance: Hooks can improve the application speed and eliminate unnecessary re-renders by handling different logic.
- Efficiency: Custom hooks simplify the development process by providing a ready-to-use set of common functionalities like form handling, API fetching, and data storage.
- Consistency: By using a shared library, developers can ensure consistent behavior and logic across multiple components or even projects.
How to create the Custom Hook Library?
Create a new directory for your custom hooks library
mkdir my-custom-hooks
cd my-custom-hooks
Now, create the components and the hooks folder in the src folder.
Initialize the Package
npm init
This will create a package.json file.
Create Your Custom Hooks
Inside this directory, create a src/ folder to store your custom hooks.
mkdir src
Add your custom hooks to the src/ folder, such as useCounter.js, useFetch.js, etc.
//src/useCounter.js
import { useState } from 'react';
const useCounter = (initialValue = 0) => {
const [count, setCount] = useState(initialValue);
const increment = () => setCount(count + 1);
const decrement = () => setCount(count - 1);
const reset = () => setCount(initialValue);
return { count, increment, decrement, reset };
};
export default useCounter;
//src/index.js
import useCounter from './useCounter';
export { useCounter };
Publish the Package
You can now publish your custom hooks package to npm.
- First, create an account on npm.
- Run the following commands to log in and publish
npm login # Log in to your npm account
npm publish # Publish the package
After this, your custom hooks library will be available as an npm package, and you can install it in any project by running:
npm install my-custom-hooks
Use Cases of Custom Hooks
Managing Form State Efficiently
Instead of writing separate state management logic in every form component, a custom hook can handle form input changes and validation.
Example: useForm
const useForm = (initialValues) => {
const [values, setValues] = useState(initialValues);
const handleChange = (event) => {
setValues({ ...values, [event.target.name]: event.target.value });
};
return [values, handleChange];
};
Fetching Data from an API
A custom hook can encapsulate API fetching logic so that different components can reuse it without duplication.
Example: useFetch
const useFetch = (url) => {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
fetch(url)
.then((response) => response.json())
.then((data) => {
setData(data);
setLoading(false);
})
.catch((error) => {
setError(error);
setLoading(false);
});
}, [url]);
return { data, loading, error };
};
Persisting Data in Local Storage
Store data in local storage and automatically sync state with it.
Example: useLocalStorage
const useLocalStorage = (key, initialValue) => {
const [storedValue, setStoredValue] = useState(() => {
const item = window.localStorage.getItem(key);
return item ? JSON.parse(item) : initialValue;
});
useEffect(() => {
window.localStorage.setItem(key, JSON.stringify(storedValue));
}, [key, storedValue]);
return [storedValue, setStoredValue];
};
Managing Window Size Responsively
A custom hook can track window resizing events to adjust UI accordingly.
Example: useWindowSize
const useWindowSize = () => {
const [size, setSize] = useState({
width: window.innerWidth,
height: window.innerHeight
});
useEffect(() => {
const handleResize = () => {
setSize({ width: window.innerWidth, height: window.innerHeight });
};
window.addEventListener("resize", handleResize);
return () => window.removeEventListener("resize", handleResize);
}, []);
return size;
};