Mastering React Hooks: Side Effects

Mastering React Hooks: Side Effects

In React, side effects are any actions that are performed outside of rendering a component, such as fetching data or updating the document title. React provides two main hooks for managing side effects: useEffect and useLayoutEffect.

useEffect

The useEffect hook allows you to perform side effects in functional components. It takes two arguments: a callback function that performs the side effect and an array of dependencies that specify when the effect should be executed. Here's an example:

import { useState, useEffect } from 'react';

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

  useEffect(() => {
    document.title = `Count: ${count}`;
  }, [count]);

  const handleClick = () => {
    setCount(count + 1);
  };

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={handleClick}>Increment</button>
    </div>
  );
}

In this example, we use useEffect to update the document title when the count state changes. We pass an array containing count as a dependency, which tells React to re-run the effect whenever count changes.

useLayoutEffect

The useLayoutEffect hook is similar to useEffect, but it runs synchronously after all DOM mutations. This means that it can be used to perform side effects that require access to the DOM, such as measuring the size of an element. Here's an example:

import { useState, useLayoutEffect } from 'react';

function ElementSize() {
  const [width, setWidth] = useState(0);
  const [height, setHeight] = useState(0);

  const measureElement = () => {
    const { width, height } = document.getElementById('element').getBoundingClientRect();
    setWidth(width);
    setHeight(height);
  };

  useLayoutEffect(() => {
    measureElement();
    window.addEventListener('resize', measureElement);

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

  return (
    <div>
      <div id="element" style={{ width: '100px', height: '100px', backgroundColor: 'red' }}></div>
      <p>Width: {width}px</p>
      <p>Height: {height}px</p>
    </div>
  );
}

In this example, we use useLayoutEffect to measure the size of a red box and display it on the page. We define a measureElement function that gets the bounding rectangle of the element and updates the state with the width and height. We then use useLayoutEffect to call measureElement and add a resize event listener to update the size when the window is resized. We pass an empty array as a dependency, which tells React to run the effect only once when the component is mounted.

Conclusion

useEffect and useLayoutEffect are the main hooks for managing side effects in React. useEffect is used for asynchronous side effects and useLayoutEffect is used for synchronous side effects that require access to the DOM. In the next article in this series, we'll cover the context hook, useContext.