It's been 4 years since React Hooks were introduced in version 16.8, and they're taking place over class-based components in React Js. Hooks allow function components to have access to state and other React features. Because of this, class components are generally no longer needed.
we will explore ten amazing React custom hooks that will enhance your development workflow and improve code reusability. React custom hooks allow you to extract and share stateful logic across multiple components, resulting in cleaner and more maintainable code. Each custom hook listed below comes with a brief description and example code to demonstrate its usage. So let's dive in!
1. useLocalStorage π§³
This hook enables you to persist data in the browser's local storage. It provides an easy way to store and retrieve values, such as user preferences or form data, between page reloads.
import { useState } from 'react';
const useLocalStorage = (key, initialValue) => {
const [value, setValue] = useState(() => {
const storedValue = localStorage.getItem(key);
return storedValue ? JSON.parse(storedValue) : initialValue;
});
const updateValue = (newValue) => {
setValue(newValue);
localStorage.setItem(key, JSON.stringify(newValue));
};
return [value, updateValue];
};
2. useFormValidation π
This hook simplifies form validation by providing reusable logic for handling form inputs, validation rules, and error messages. It helps streamline the process of validating user input and displaying error feedback.
import { useState } from 'react';
const useFormValidation = (initialState, validate) => {
const [values, setValues] = useState(initialState);
const [errors, setErrors] = useState({});
const [isSubmitting, setIsSubmitting] = useState(false);
const handleChange = (event) => {
const { name, value } = event.target;
setValues((prevState) => ({
...prevState,
[name]: value,
}));
};
const handleSubmit = (event) => {
event.preventDefault();
setErrors(validate(values));
setIsSubmitting(true);
};
return { values, errors, handleChange, handleSubmit, isSubmitting };
};
3. useMediaQuery π²
This hook allows you to conditionally render components based on the device's screen size or media queries. It simplifies responsiveness and enables you to create adaptive user interfaces.
import { useState, useEffect } from 'react';
const useMediaQuery = (query) => {
const [matches, setMatches] = useState(false);
useEffect(() => {
const mediaQuery = window.matchMedia(query);
setMatches(mediaQuery.matches);
const handleChange = (event) => {
setMatches(event.matches);
};
mediaQuery.addEventListener('change', handleChange);
return () => {
mediaQuery.removeEventListener('change', handleChange);
};
}, [query]);
return matches;
};
4. useDebounce π
This hook helps optimize performance by debouncing expensive operations. It delays the execution of a function until a certain amount of time has passed since the last invocation, reducing unnecessary recalculations.
import { useState, useEffect } from 'react';
const useDebounce = (value, delay) => {
const [debouncedValue, setDebouncedValue] = useState(value);
useEffect(() => {
const timer = setTimeout(() => {
setDebouncedValue(value);
}, delay);
return () => {
clearTimeout(timer);
};
}, [value, delay]);
return debouncedValue;
};
5. usePagination π
This hook simplifies pagination logic by providing state and functions to handle page navigation. It helps in dividing large sets of data into manageable chunks and improves the user experience.
import { useState } from 'react';
const usePagination = (initialPage, itemsPerPage, totalItems) => {
const [currentPage, setCurrentPage] = useState(initialPage);
const totalPages = Math.ceil(totalItems / itemsPerPage);
const nextPage = () => {
setCurrentPage((prevPage) => Math.min(prevPage + 1, totalPages));
};
const prevPage = () => {
setCurrentPage((prevPage) => Math.max(prevPage - 1, 1));
};
const goToPage = (page) => {
setCurrentPage(Math.min(Math.max(page, 1), totalPages));
};
const startIndex = (currentPage - 1) * itemsPerPage;
const endIndex = startIndex + itemsPerPage;
const paginationData = {
currentPage,
totalPages,
nextPage,
prevPage,
goToPage,
startIndex,
endIndex,
};
return paginationData;
};
6. useDarkMode π‘
This hook enables you to implement a dark mode feature in your React application. It manages the state of the dark mode and provides a convenient way to toggle between light and dark themes.
import { useState, useEffect } from 'react';
const useDarkMode = () => {
const [isDarkMode, setIsDarkMode] = useState(false);
useEffect(() => {
const body = document.body;
if (isDarkMode) {
body.classList.add('dark-mode');
} else {
body.classList.remove('dark-mode');
}
}, [isDarkMode]);
const toggleDarkMode = () => {
setIsDarkMode((prevMode) => !prevMode);
};
return { isDarkMode, toggleDarkMode };
};
7. useKeyPress πΉ
This hook allows you to detect keyboard key presses and trigger specific actions based on the pressed keys. It is useful for implementing keyboard shortcuts or interactive features that respond to user input.
import { useState, useEffect } from 'react';
const useKeyPress = (targetKey) => {
const [isKeyPressed, setIsKeyPressed] = useState(false);
const handleKeyDown = ({ key }) => {
if (key === targetKey) {
setIsKeyPressed(true);
}
};
const handleKeyUp = ({ key }) => {
if (key === targetKey) {
setIsKeyPressed(false);
}
};
useEffect(() => {
window.addEventListener('keydown', handleKeyDown);
window.addEventListener('keyup', handleKeyUp);
return () => {
window.removeEventListener('keydown', handleKeyDown);
window.removeEventListener('keyup', handleKeyUp);
};
}, [targetKey]);
return isKeyPressed;
};
8. useCopyToClipboard π
This hook provides a simple way to copy text to the clipboard. It is useful for implementing copy functionality in your React application, such as copying a generated link or sharing content.
import { useState } from 'react';
const useCopyToClipboard = () => {
const [isCopied, setIsCopied] = useState(false);
const copyToClipboard = (text) => {
navigator.clipboard.writeText(text)
.then(() => setIsCopied(true))
.catch(() => setIsCopied(false));
};
return { isCopied, copyToClipboard };
};
9. useScrollToTop π§πΌββοΈ
This hook allows you to scroll to the top of the page programmatically. It is useful for scenarios where you want to provide a smooth scrolling experience, especially when navigating to a new section.
import { useEffect } from 'react';
const useScrollToTop = () => {
useEffect(() => {
window.scrollTo({ top: 0, behavior: 'smooth' });
}, []);
};
10. useInterval βοΈ
This hook provides a simple way to execute a function at a specified interval. It is useful for implementing features like real-time updates or timed animations.
import { useEffect, useRef } from 'react';
const useInterval = (callback, delay) => {
const savedCallback = useRef();
useEffect(() => {
savedCallback.current = callback;
}, [callback]);
useEffect(() => {
const tick = () => {
savedCallback.current();
};
const intervalId = setInterval(tick, delay);
return () => {
clearInterval(intervalId);
};
}, [delay]);
};
These are just standard definitions of custom hooks, but you can always customize them as per your own usage.
Find more about custom hooks from this amazing website usehooks.
Comment down the thoughts and hooks you like most and gonna use in your next projectsπ.
Thank you π«Ά.
Top comments (1)
So helpful and informative ! ππ»