How to create custom hooks in react

react jsx

In ReactJS, hooks are a powerful feature that allow you to use state, lifecycle methods, and other React features in functional components. While React provides built-in hooks like useStateuseEffect, and useContext, there may be cases where you need to extract logic into reusable functions that are specific to your application. This is where custom hooks come in.

Custom hooks allow you to extract logic that can be shared across multiple components, helping you avoid code duplication and making your code cleaner and more maintainable.

In this blog post, we’ll explore how to create custom hooks in ReactJS, understand when to use them, and look at some examples.


What is a Custom Hook?

custom hook is a function that lets you reuse stateful logic in React components. Custom hooks are prefixed with the use keyword, as a convention, so that React can identify them as hooks.

Custom hooks can:

  • Share stateful logic across components
  • Encapsulate complex logic inside a reusable function
  • Return values (such as state and functions) that can be used inside components

Custom hooks can utilize built-in hooks like useStateuseEffectuseReducer, etc., and return any data or functions that are required.


When to Use Custom Hooks?

You should consider creating custom hooks when:

  1. You have reusable logic: If you find yourself using the same logic across multiple components (e.g., fetching data from an API), it’s a good idea to extract it into a custom hook.
  2. You want to share stateful logic: If multiple components need access to a similar stateful logic (e.g., form handling, input validation), custom hooks can help avoid redundancy.
  3. You need encapsulation: If your logic involves complex state or side effects, custom hooks help encapsulate this complexity, making your components simpler and easier to maintain.

How to Create a Custom Hook

Creating a custom hook is straightforward. You define a function that can use other React hooks (such as useStateuseEffect, etc.) and then return values or functions.

Let’s walk through the steps to create a custom hook.

Step 1: Define the Custom Hook Function

To start, create a function in your component or in a separate file. This function will use React’s built-in hooks and manage any internal state or side effects.

Step 2: Use React Hooks Inside Your Custom Hook

Inside the custom hook, you can use built-in hooks like useStateuseEffect, and useRef to manage state, side effects, or refs.

Step 3: Return Data from the Hook

The custom hook should return whatever data, methods, or state you need to expose to the component using the hook.

Example 1: A Custom Hook for Fetching Data

Let’s create a simple custom hook that fetches data from an API.

In this example, useFetch is a custom hook that accepts a url parameter and returns dataloading, and error states. You can use this hook in any component to fetch data.

Step 4: Use the Custom Hook in a Component

Now that we have the useFetch hook, we can use it in a component:

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

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

 if (loading) return <div>Loading...</div>;
 if (error) return <div>Error: {error.message}</div>;

 return (
   <div>
     <h1>Data from API</h1>
     <pre>{JSON.stringify(data, null, 2)}</pre>
   </div>
 );
 
 }

export default App;


In this component, we're calling the useFetch hook, passing a URL to it. The hook returns the dataloading, and error states, which we then use to render the appropriate UI.

Example 2: A Custom Hook for Form Handling

Another common scenario is form handling. Let’s create a custom hook to manage form inputs and validation.

import { useState } from 'react';

function useForm(initialState) {
 const [formData, setFormData] = useState(initialState);

 // Handle input changes
 const handleChange = (e) => {
   const { name, value } = e.target;
   setFormData({
     ...formData,
     [name]: value,
   });
 };

 // Handle form submission
 const handleSubmit = (e, callback) => {
   e.preventDefault();
   callback(formData);
 };

 return { formData, handleChange, handleSubmit };
}

This useForm custom hook returns an object containing the form data, a function to handle input changes (handleChange), and a handleSubmit function to handle form submission.

Using useForm in a Component

import React from 'react';
import { useForm } from './useForm';

function ContactForm() {
 const { formData, handleChange, handleSubmit } = useForm({
   name: '',
   email: '',
 });

 const submitForm = (data) => {
   console.log('Form Submitted:', data);
 };

 return (
   <form onSubmit={(e) => handleSubmit(e, submitForm)}>
     <div>
       <label>Name</label>
       <input
         type="text"
         name="name"
         value={formData.name}
         onChange={handleChange}
       />
     </div>
     <div>
       <label>Email</label>
       <input
         type="email"
         name="email"
         value={formData.email}
         onChange={handleChange}
       />
     </div>
     <button type="submit">Submit</button>
   </form>
 );
}

export default ContactForm;

In this example, the useForm custom hook helps manage the form state and provides an easy-to-use API to handle input changes and form submission.


Tips for Creating Custom Hooks

  • Start with simple logic: Begin by extracting simple logic into custom hooks and then build more complex hooks as needed.
  • Naming convention: Always start your custom hook names with the use keyword (e.g., useFormuseFetch), as this is a React convention and helps React identify your custom hooks.
  • Use other hooks inside custom hooks: Custom hooks can call built-in hooks like useStateuseEffectuseReducer, etc.
  • Return useful data: Your custom hook should return the state or methods that a component needs to function properly.

Conclusion

Custom hooks are a powerful feature in React that allow you to reuse stateful logic across your components. By creating custom hooks, you can separate concerns, reduce code duplication, and make your components cleaner and more maintainable.

To get started, identify any logic in your components that can be reused or abstracted, and then move that logic into a custom hook. This will not only simplify your components but also help you manage your application’s state and side effects more efficiently.

Leave a Reply

Your email address will not be published. Required fields are marked *