Web Development

React Hooks: useState and useEffect

Why Hooks?

Hooks let function components hold state and run side effects — things that used to require class components. useState and useEffect cover the vast majority of everyday needs.

useState: Component Memory

import { useState } from "react"; function Counter() { const [count, setCount] = useState(0); return ( <button onClick={() => setCount(count + 1)}> Clicked {count} times </button> ); }

useState(0) returns the current value and a function to update it. Calling that function triggers a re-render with the new value.

Updating State Based on Previous State

setCount(prevCount => prevCount + 1);

Use this function form when the new value depends on the old one — it avoids bugs from stale values in fast-updating scenarios.

useEffect: Side Effects

useEffect runs code after render — fetching data, subscribing to events, or manually updating the DOM.

import { useState, useEffect } from "react"; function TutorialList() { const [tutorials, setTutorials] = useState([]); useEffect(() => { fetch("/api/tutorials") .then(res => res.json()) .then(data => setTutorials(data)); }, []); // empty array = run once, on mount return <ul>{tutorials.map(t => <li key={t.id}>{t.title}</li>)}</ul>; }

The Dependency Array

The second argument to useEffect controls when it re-runs:

  • [] — runs once, after the first render
  • [someValue] — re-runs whenever someValue changes
  • omitted entirely — runs after every render (rarely what you want)

Cleaning Up

useEffect(() => { const id = setInterval(() => console.log("tick"), 1000); return () => clearInterval(id); // cleanup on unmount }, []);

Practice Exercise

Build a component that fetches a list of tutorials on mount, shows a loading state while waiting, and displays an error message if the fetch fails.

Leave a Reply

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