Mastering React Hooks: A Deep Dive into useState, useEffect, and Custom Hooks

Revolutionizing React with Hooks

React Hooks, introduced in React 16.8, fundamentally changed how we write React components. They allow you to use state and other React features without writing a class, promoting a more functional and concise codebase. This article delves into the most commonly used hooks and demonstrates how to create your own custom hooks for maximum reusability.

useState: Managing Component State

useState is the most basic hook, enabling functional components to manage local state. It returns a pair: the current state value and a function that lets you update it.

import React, { useState } from 'react';

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

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

This simple hook replaces this.state and this.setState from class components, making state management more straightforward.

useEffect: Handling Side Effects

useEffect is your go-to hook for performing side effects in functional components, such as data fetching, subscriptions, or manually changing the DOM. It runs after every render, but you can control when it re-runs by providing a dependency array.

import React, { useState, useEffect } from 'react';

function DataFetcher() {
  const [data, setData] = useState(null);

  useEffect(() => {
    fetch('https://api.example.com/data')
      .then(response => response.json())
      .then(json => setData(json));
  }, []); // Empty array means run once on mount
  
  return (
    <div>
      {data ? <p>{data.message}</p> : <p>Loading...</p>}
    </div>
  );
}

Properly managing the dependency array is crucial to prevent infinite loops or unnecessary re-runs.

Custom Hooks: Reusing Logic

One of the most powerful aspects of Hooks is the ability to create your own custom hooks. A custom hook is a JavaScript function whose name starts with "use" and that may call other hooks. They allow you to extract component logic into reusable functions.

For example, a useWindowSize hook could encapsulate the logic for tracking window dimensions:

import { useState, useEffect } from 'react';

function useWindowSize() {
  const [windowSize, setWindowSize] = useState({
    width: undefined,
    height: undefined,
  });

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

    window.addEventListener('resize', handleResize);
    handleResize(); // Set initial size

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

  return windowSize;
}

// Usage in a component:
// const { width, height } = useWindowSize();

Custom hooks promote code sharing, reduce duplication, and make your components cleaner and easier to understand. Mastering them is key to writing truly efficient and scalable React applications.

OTH

Manage and simulate agentic workflows

Get the latest product news and behind the scenes updates.