Custom Hooks: Creating Reusable Logic in React JS

React hooks allow you to manage state and side effects in functional components, making them a powerful tool for building interactive UIs. While React provides several built-in hooks like useState, useEffect, and useContext, one of the most useful features is the ability to create custom hooks. Custom hooks allow you to encapsulate reusable logic and share it across different components, improving code organization and maintainability.

What is a Custom Hook?

A custom hook is a JavaScript function whose name starts with "use" and that can call other React hooks inside it. By using custom hooks, you can extract component logic into reusable functions, allowing you to share stateful logic without changing the component hierarchy.

Why Use Custom Hooks?

  • Reusability: Custom hooks allow you to reuse logic across different components without duplicating code.
  • Code organization: Custom hooks help you organize your code by separating concerns and grouping related logic together.
  • Improved maintainability: By centralizing logic in custom hooks, you can make your components cleaner and easier to maintain.

Creating a Custom Hook

To create a custom hook, simply define a function that uses React hooks internally. Custom hooks can return any value (state, functions, etc.), which can then be used in the components that call them.

Example 1: Custom Hook to Handle Window Resize

Here’s an example of a custom hook that listens for window resizing and provides the window dimensions.

          
              import { useState, useEffect } from 'react';

              function useWindowSize() {
                  const [windowSize, setWindowSize] = useState({
                      width: window.innerWidth,
                      height: window.innerHeight,
                  });

                  useEffect(() => {
                      const handleResize = () => {
                          setWindowSize({
                              width: window.innerWidth,
                              height: window.innerHeight,
                          });
                      };

                      window.addEventListener('resize', handleResize);
                      return () => {
                          window.removeEventListener('resize', handleResize);
                      };
                  }, []);

                  return windowSize;
              }

              export default useWindowSize;
          
      

This custom hook, useWindowSize, tracks the current width and height of the window. It sets up an event listener for the window resize event, and whenever the window is resized, it updates the state with the new dimensions.

Example 2: Using Custom Hook in a Component

Now let’s use this custom hook in a component to display the current window size.

          
              import React from 'react';
              import useWindowSize from './useWindowSize';

              function App() {
                  const { width, height } = useWindowSize();

                  return (
                      

Window Size

Width: {width}px

Height: {height}px

); } export default App;

In the above example, the App component calls the useWindowSize custom hook to get the current window dimensions. The returned values (width and height) are displayed in the component.

Example 3: Custom Hook for Fetching Data

Let’s create another custom hook for handling data fetching. This custom hook can be reused to fetch data in any component.

          
              import { useState, useEffect } from 'react';

              function useFetch(url) {
                  const [data, setData] = useState(null);
                  const [loading, setLoading] = useState(true);
                  const [error, setError] = useState(null);

                  useEffect(() => {
                      const fetchData = async () => {
                          try {
                              const response = await fetch(url);
                              const result = await response.json();
                              setData(result);
                          } catch (error) {
                              setError(error);
                          } finally {
                              setLoading(false);
                          }
                      };

                      fetchData();
                  }, [url]);

                  return { data, loading, error };
              }

              export default useFetch;
          
      

The useFetch custom hook fetches data from a given URL and returns the data, loading state, and error state. It uses useEffect to perform the side-effect of fetching the data when the component mounts or when the URL changes.

Using the useFetch Hook

Now let’s use this useFetch hook in a component to fetch and display some data.

          
              import React from 'react';
              import useFetch from './useFetch';

              function App() {
                  const { data, loading, error } = useFetch('https://api.example.com/data');

                  if (loading) {
                      return 

Loading...

; } if (error) { return

Error: {error.message}

; } return (

Data

{JSON.stringify(data, null, 2)}
); } export default App;

In this example, we use the useFetch hook to fetch data from an API. The component renders loading text while the data is being fetched, and it displays the data once the fetch operation is complete.

Best Practices for Custom Hooks

  • Encapsulate reusable logic: Custom hooks should encapsulate logic that can be reused across components. Avoid writing hooks that are tightly coupled to a specific component’s state or behavior.
  • Use meaningful names: Give your custom hooks descriptive names that clearly indicate the functionality they provide, such as useWindowSize, useLocalStorage, or useForm.
  • Follow the rules of hooks: Just like React’s built-in hooks, custom hooks must follow the rules of hooks, which include calling hooks at the top level and within functional components.

Conclusion

Custom hooks are a powerful feature in React that help you abstract and reuse logic across different components. By creating custom hooks, you can keep your components clean and maintainable while also improving code reusability. Whether you're handling side effects, managing form state, or fetching data, custom hooks provide a flexible and efficient way to organize your logic in React applications.





Advertisement