#react #tutorial #advanced

Day 9: Custom Hooks

Day 9: Custom Hooks

One of the best features of React Hooks is that you can build your own. A Custom Hook is just a JavaScript function whose name starts with “use” and that may call other hooks.

Why Custom Hooks?

They allow you to extract stateful logic from a component so it can be tested independently and reused.

Example 1: useFetch

Fetching data is common. Instead of writing useEffect and fetch in every component, let’s make a hook.

// useFetch.js
import { useState, useEffect } from 'react';

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

  useEffect(() => {
    setLoading(true);
    fetch(url)
      .then(res => res.json())
      .then(data => {
        setData(data);
        setLoading(false);
      })
      .catch(err => {
        setError(err);
        setLoading(false);
      });
  }, [url]); // Re-run if URL changes

  // Return whatever you want: array, object, single value
  return { data, loading, error };
}

Usage:

// UserList.jsx
import { useFetch } from './useFetch';

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

  if (loading) return <p>Loading...</p>;
  if (error) return <p>Error!</p>;

  return (
    <ul>
      {users.map(u => <li key={u.id}>{u.name}</li>)}
    </ul>
  );
}

Now any component can fetch data with one line of code!

Example 2: useWindowWidth

Let’s track the window size.

import { useState, useEffect } from 'react';

function useWindowWidth() {
  const [width, setWidth] = useState(window.innerWidth);

  useEffect(() => {
    const handleResize = () => setWidth(window.innerWidth);
    
    window.addEventListener('resize', handleResize);
    
    // Cleanup is crucial here!
    return () => window.removeEventListener('resize', handleResize);
  }, []);

  return width;
}

Usage:

function App() {
  const width = useWindowWidth();
  return <p>Window width is: {width}px</p>;
}

Rules of Hooks (Review)

  1. Only call Hooks at the top level. Don’t call them inside loops, conditions, or nested functions.
  2. Only call Hooks from React function components (or other custom hooks).

Homework for Day 9:

  1. Create a useLocalStorage hook.
  2. It should work like useState, but it syncs the value to the browser’s Local Storage.
  3. If the user refreshes the page, the state should persist.

Tomorrow is our final day: Performance Optimization!