Search Knowledge

© 2026 LIBREUNI PROJECT

Modern JavaScript & Ecosystem / Frameworks: React

React Hooks: Managing Logic and Lifecycle

The Functional Revolution

Before React 16.8, state and lifecycle methods were exclusive to Class Components. Hooks were introduced to allow functional components to “hook into” React state and lifecycle features. This led to flatter component trees and better logic reuse.

useState: Preserving Local State

The useState hook allows a component to maintain persistent data across re-renders. It returns an array with two elements: the current state value and a function to update it.

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

When setCount is called, React schedules a re-render of the component.

useEffect: Handling Side Effects

Side effects, such as data fetching, subscriptions, or manual DOM manipulations, must be isolated from the rendering logic. useEffect runs after the component renders.

It takes two arguments:

  1. Effect Function: The logic to execute.
  2. Dependency Array: An array of values that the effect depends on. The effect only re-runs if one of these values changes.

The Cleanup Phase

If an effect creates a subscription or a timer, it must return a cleanup function to prevent memory leaks when the component unmounts or before the effect re-runs.

javascript
1// Conceptual simulation of useEffect cleanup
2function ChatRoom({ roomId }) {
3 console.log("Connecting to room:", roomId);
4 
5 // Return cleanup function
6 return () => {
7 console.log("Disconnecting from room:", roomId);
8 };
9}
10 
11// Imagine roomId changes from 1 to 2
12const cleanup = ChatRoom({ roomId: 1 });
13cleanup(); // React runs cleanup before switching
14ChatRoom({ roomId: 2 });

useRef: Persistent References

Unlike useState, changing a value in useRef does not trigger a re-render. It is primarily used for:

  1. Accessing DOM nodes directly.
  2. Storing values that need to persist for the lifetime of the component but don’t affect the UI (e.g., timer IDs).

The Rules of Hooks

To ensure that React can correctly associate internal state with functional calls, hooks must follow two strict rules:

  1. Only Call Hooks at the Top Level: Do not call hooks inside loops, conditions, or nested functions.
  2. Only Call Hooks from React Functions: Call them from React functional components or custom hooks.

Custom Hooks: Extracts and Reuses

Custom hooks allow you to extract component logic into reusable functions. This is the primary way React developers share stateful logic between different components without using complex patterns like Render Props or HOCs.

function useWindowWidth() {
  const [width, setWidth] = useState(window.innerWidth);
  useEffect(() => {
    const handleResize = () => setWidth(window.innerWidth);
    window.addEventListener('resize', handleResize);
    return () => window.removeEventListener('resize', handleResize);
  }, []);
  return width;
}

What happens if you provide an empty array [] as the second argument to useEffect?