React Hooks Introduction: useState and useEffect

React 16.8 shipped with Hooks, and they’ve changed how I write React components. No more class components for simple state management. Here’s my introduction to the two most important hooks.

The Problem with Classes

Class components work, but they’re verbose. You need constructors, binding methods, lifecycle methods spread across the component. Hooks let you use state and effects in function components.

useState

The simplest hook. It returns a value and a setter:

import React, { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);
  
  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>+</button>
      <button onClick={() => setCount(count - 1)}>-</button>
      <button onClick={() => setCount(0)}>Reset</button>
    </div>
  );
}

You can have multiple state variables:

function Form() {
  const [name, setName] = useState('');
  const [email, setEmail] = useState('');
  const [isSubmitting, setIsSubmitting] = useState(false);
  
  // Or use an object
  const [form, setForm] = useState({ name: '', email: '' });
}

useEffect

useEffect is for side effects: data fetching, subscriptions, DOM manipulation. It runs after render:

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

function UserProfile({ userId }) {
  const [user, setUser] = useState(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    async function fetchUser() {
      setLoading(true);
      const response = await fetch(`/api/users/${userId}`);
      const data = await response.json();
      setUser(data);
      setLoading(false);
    }
    
    fetchUser();
  }, [userId]); // Re-run when userId changes

  if (loading) return <div>Loading...</div>;
  return <div>Hello, {user.name}</div>;
}

The Dependency Array

The second argument to useEffect controls when it runs:

// Runs after every render
useEffect(() => { ... });

// Runs once on mount
useEffect(() => { ... }, []);

// Runs when dependencies change
useEffect(() => { ... }, [userId, something]);

Cleanup

Return a function from useEffect for cleanup:

useEffect(() => {
  const subscription = dataSource.subscribe(handleData);
  
  return () => {
    subscription.unsubscribe();
  };
}, [dataSource]);

Rules of Hooks

  • Only call hooks at the top level (not in loops or conditions)
  • Only call hooks from React functions
  • Name custom hooks starting with “use”

References


Discover more from C4: Container, Code, Cloud & Context

Subscribe to get the latest posts sent to your email.

Leave a comment

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.