React Fundamentals

0% completed

Previous
Next
Understanding Custom Hooks

Custom hooks are JavaScript functions that allow you to reuse stateful logic across components. They begin with the prefix use (e.g., useFetch, useAuth), which is a convention established by React to distinguish hooks from regular functions.

This prefix also indicates that these functions follow the rules of hooks, such as only being called at the top level of a component or another hook.

The key idea is that custom hooks allow you to encapsulate logic that can be reused across multiple components. These hooks can utilize other React hooks, such as useState or useEffect, to manage state, handle side effects, or interact with component lifecycle events.

Why Use Custom Hooks?

Here are some common scenarios where custom hooks are perfect for:

  1. Code Reusability: Consolidate logic used in multiple components.
  2. Abstraction: Simplify components by moving complex logic into separate hooks.
  3. Clean Components: Reduce clutter by delegating side effects or logic into a custom hook.
  4. Improved Testing: Isolate logic for better testability.

How to Create a Custom Hook

Let’s walk through building a custom hook with a simple example. Suppose you want to track the current window width and respond to changes.

Step 1: Define the Hook

Create a new file, say useWindowWidth.js, and define your custom hook.

import { useState, useEffect } from "react"; function useWindowWidth() { const [windowWidth, setWindowWidth] = useState(window.innerWidth); useEffect(() => { const handleResize = () => setWindowWidth(window.innerWidth); // Add event listener when the component mounts window.addEventListener("resize", handleResize); // Cleanup the event listener when the component unmounts return () => window.removeEventListener("resize", handleResize); }, []); return windowWidth; } export default useWindowWidth;

Step 2: Use the Hook in a Component

Now, you can use this hook in any component to access the current window width.

import React from "react"; import useWindowWidth from "./useWindowWidth"; function ResponsiveComponent() { const windowWidth = useWindowWidth(); return ( <div> <h1>Current Window Width: {windowWidth}px</h1> {windowWidth > 768 ? ( <p>You’re using a large screen!</p> ) : ( <p>You’re using a small screen!</p> )} </div> ); } export default ResponsiveComponent;

To use the functionality of the useWindowWidth function, all you need to do is:

  • Import the custom hook function into a desired file.
  • Assign the function to a variable.
  • Use the variable to access the custom hook functionality.

Key Principles for Custom Hooks

  1. Start with use: Always prefix custom hooks with use word. This is not just a naming convention; it ensures React can identify them as hooks, enabling features like the Rules of Hooks.

  2. Follow the Rules of Hooks: Custom hooks must adhere to the same rules as built-in hooks:

    • Only call hooks at the top level of the function.
    • Only call hooks from functional components or other custom hooks.
  3. Return Values: Custom hooks can return any value: a state, a function, an object, or a combination.

Example Two: Fetching Data with a Custom Hook

Let’s create another custom hook to handle API calls.

Step 1: Define the Hook

Create a new file, say useFetch.js, and define your custom hook.

import { useState, useEffect } from "react"; function useFetch(url) { const [data, setData] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); useEffect(() => { let isMounted = true; const fetchData = async () => { setLoading(true); try { const response = await fetch(url); if (!response.ok) { throw new Error(`Error: ${response.statusText}`); } const result = await response.json(); if (isMounted) { setData(result); } } catch (err) { if (isMounted) { setError(err.message); } } finally { if (isMounted) { setLoading(false); } } }; fetchData(); return () => { isMounted = false; }; }, [url]); return { data, loading, error }; } export default useFetch;

Step 2: Use the Hook in a Component

Now, you can use this hook in any component to fetch data from an API. All you need to do is to insert the url where you want to fetch data from.

import React from "react"; import useFetch from "./useFetch"; function UserList() { const { data, loading, error } = useFetch("https://jsonplaceholder.typicode.com/users"); if (loading) return <p>Loading...</p>; if (error) return <p>Error: {error}</p>; return ( <ul> {data.map((user) => ( <li key={user.id}>{user.name}</li> ))} </ul> ); } export default UserList;

Benefits of Custom Hooks

  1. Scalability: Custom hooks make your application more scalable by encouraging modular and reusable logic.
  2. Consistency: Ensures that shared logic behaves consistently across components.
  3. Readability: Break down complex logic into understandable and maintainable pieces.

Common Use Cases for Custom Hooks

Custom hooks are commonly useful for certain tasks such as:

  1. API Calls: Handling data fetching, caching, and error handling.
  2. Authentication: Managing user authentication and permissions.
  3. Responsive Design: Detecting screen size or orientation changes.
  4. Forms: Managing form states and validations.

Tips for Creating Effective Custom Hooks

  1. Keep Hooks Simple: Focus on one task or responsibility per hook.
  2. Document Your Hooks: Provide clear comments or documentation to describe their purpose and usage.
  3. Test Thoroughly: Ensure your hooks work as expected in various scenarios.

.....

.....

.....

Like the course? Get enrolled and start learning!
Previous
Next