Tutorial: React Hooks Explained

Understand and use React Hooks (`useState`, `useEffect`) to manage state and side effects in functional components.

By Upingi Team / Tutorial Level: Intermediate

What are React Hooks?

React Hooks allow you to use state and other React features in functional components, which were previously only available in class components. They make component logic more reusable and easier to understand.

Hooks like `useState` and `useEffect` are fundamental for building modern React applications.

Prerequisites

  • Basic React Knowledge: Understanding React components, props, and JSX.
  • JavaScript (ES6+): Familiarity with modern JavaScript features like arrow functions and destructuring.
  • Node.js & npm/yarn: A React development environment setup (e.g., using Create React App).

Let's hook into React features!

Chapter 1: Managing State with `useState`

The `useState` hook lets you add state variables to functional components.

  1. Import `useState`: `import React, { useState } from 'react';`.
  2. Declare State: Inside your component, call `useState` with the initial state: `const [count, setCount] = useState(0);`. This returns the current state (`count`) and a function to update it (`setCount`).
  3. Read State: Use the state variable directly in your JSX: `

    You clicked { count } times

    `.
  4. Update State: Call the update function (e.g., `setCount`) usually within an event handler: ``. Updating state triggers a re-render.

Build a simple counter component using `useState`.

Chapter 2: Handling Side Effects with `useEffect`

The `useEffect` hook lets you perform side effects in functional components. Common side effects include data fetching, setting up subscriptions, and manually changing the DOM.

Basic Usage:

Import it alongside `useState`: `import React, { useState, useEffect } from 'react';`. Then, call `useEffect` inside your component, passing it a function (the "effect").

useEffect(() => {
  // This code runs after every render
  document.title = `You clicked ${count} times`;
}); // No dependency array: runs on every render

Controlling When Effects Run (Dependency Array):

The second argument to `useEffect` is the dependency array. It controls when the effect function re-runs:

  • No array (like above): The effect runs after *every* render. Use this sparingly.
  • Empty array `[]`: The effect runs *only once* after the initial render. Useful for setup tasks like data fetching or starting timers.
  • Array with variables `[count, name]`: The effect runs after the initial render *and* whenever any value in the array changes. This is the most common use case.
useEffect(() => {
  console.log('Count changed to:', count);
}, [count]); // Only re-run the effect if count changes

useEffect(() => {
  // Fetch data only on initial render
  fetchData();
}, []); // Empty array: runs only once

Cleanup Function:

If your effect sets up something that needs to be cleaned up (like a subscription or timer), you can return a function from your effect. React will run this cleanup function before the component unmounts or before the effect re-runs.

useEffect(() => {
  const timerId = setInterval(() => {
    console.log('Tick!');
  }, 1000);

  // Cleanup function
  return () => {
    clearInterval(timerId);
    console.log('Timer cleared!');
  };
}, []); // Run once, cleanup on unmount

Conclusion & Next Steps

You've learned the basics of `useState` for state management and the purpose of `useEffect` for side effects in React functional components. Hooks are essential tools for building modern React apps.

Explore more Hooks:

  • `useContext` for accessing context.
  • `useReducer` for more complex state logic.
  • `useRef` for accessing DOM elements or storing mutable values.
  • `useMemo` and `useCallback` for performance optimizations.
  • Creating custom Hooks to encapsulate reusable logic.