React Custom Hooks: A Fun and Easy Guide for Beginners
Tags: webdev, react, beginners, tutorial
Published: 2023-06-19 09:21:23

Welcome to the wonderful world of React Custom Hooks! In this fun and easy-to-read guide, we'll explore the importance of custom hooks in React and learn how to create them step-by-step. So, buckle up and let's dive right in! 🚀

## Why Custom Hooks 

Custom Hooks offer the flexibility of sharing logic across multiple components, which wasn't possible before in React components. They allow you to write reusable and maintainable code, covering a wide range of use cases like form handling, animation, subscriptions, timers, and many more.

In this article we will create few custom hooks which has some practical application. 

## Example 1: Simple Hook to change title of Document
Let's create a custom hook that updates the document title whenever a value changes. This is a simple example, but it's a great way to get started with custom hooks.

- Create a new JavaScript function: Custom Hooks are functions with the name prefixed with the word `use`. This naming convention lets us know that the function follows the rules of Hooks.

- Add the useEffect Hook: Since we want to update the document title whenever the title value changes, we'll use the useEffect Hook inside our custom Hook.

```javascript
import { useEffect } from 'react';

function useDocumentTitle(title) {
  useEffect(() => {
    document.title = title;
  }, [title]);
}

```

- Use the custom Hook in a component: Now that we've created our custom Hook, we can use it in any functional component that needs to update the document title

```javascript
import React, { useState } from 'react';
import useDocumentTitle from './useDocumentTitle';

function App() {
  const [count, setCount] = useState(0);

  useDocumentTitle(`You clicked ${count} times`);

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>Click me</button>
    </div>
  );
}

```


## Example 2: Simple Counter Hook
This hook will help us manage the state of a counter and provide functions to increment and decrement the counter value. Here's the code:

Custom Hook:
```javascript
import { useState } from "react";

function useCounter(initialValue = 0) {
  const [count, setCount] = useState(initialValue);

  function increment() {
    setCount(count + 1);
  }

  function decrement() {
    setCount(count - 1);
  }

  function reset() {
    setCount(initialValue);
  }

  return { count, increment, decrement, reset };
}

export default useCounter;
```

Now use this custom hook in any component that needs a simple counter functionality:

```javascript
import useCounter from "./useCounter"

export default function App() {
  const { count, increment, decrement, reset } = useCounter(15);
  return (
    <div>
      <button onClick={decrement}>-</button>
      <span>{count}</span>
      <button onClick={increment}>+</button>
      <button onClick={reset}>Reset</button>
    </div>
  );
}
```

## Example 3: API Data Fetching Hook
Imagine you want to fetch data from an API and display it in your component. You can create a custom hook to handle data fetching and manage the state for you. Here's an example:

```javascript
import { useState, useEffect } from 'react';

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

  useEffect(() => {
    setLoading(true);

    fetch(url)
      .then((response) => {
        if (!response.ok) {
          throw new Error('Failed to fetch data');
        }
        return response.json();
      })
      .then((data) => {
        setData(data);
        setLoading(false);
      })
      .catch((error) => {
        setError(error.message);
        setLoading(false);
      });
  }, [url]);

  return { data, loading, error };
}

```
This custom hook fetches data from a given URL and manages the state for data, loading, and error. Use this hook in your components as following:

```javascript
import useFetchData from './useFetchData';

function DataDisplay({ url }) {
  const { data, loading, error } = useFetchData(url);

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

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

export default DataDisplay;

```

## Conclusion
You’ll likely often use custom Hooks created by others checkout this awesome collection of modern hooks [useHooks](https://usehooks.com/), but occasionally you might write one yourself!

Custom Hooks open up new ways of writing components and allow you to tailor functionality to your liking. They help you write cleaner, more maintainable code and minimize the need for class-based components. Don't be afraid to experiment and create your own custom Hooks for different use cases. And remember, have fun while you're at it! 😄