As diferenças entre useEffect e useLayoutEffect

Trabalhando com React, frequentemente nos deparamos com situações que exigem lidar com efeitos colaterais nos componentes. Duas opções populares para isso são os hooks useEffect e useLayoutEffect. Embora ambos sirvam para realizar operações secundárias, eles têm diferenças cruciais em termos de funcionamento e timing.

useEffect: O useEffect é um hook assíncrono, ideal para operações que não precisam ser executadas de forma síncrona com a renderização do componente. Ele é mais adequado para tarefas que não afetam diretamente a interface do usuário ou o layout da página. A principal característica do useEffect é que ele é executado após o navegador exibir a tela. Isso o torna eficiente para tarefas não críticas para a renderização, como chamadas de API, manipulação de estados ou subscrições a eventos.

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

const ExampleComponent = () => {
  const [data, setData] = useState(null);

  useEffect(() => {
    // Simulando uma chamada de API assíncrona
    const fetchData = async () => {
      const response = await fetch('https://api.example.com/data');
      const result = await response.json();
      setData(result);
    };

    fetchData(); // Chamada da função para buscar dados
  }, []);

  return (
    <div>
      {data ? (
        <p>Dados carregados: {data}</p>
      ) : (
        <p>Carregando...</p>
      )}
    </div>
  );
};

export default ExampleComponent;

Exemplo de useEffect

Neste exemplo, o useEffect é utilizado para buscar dados de uma API assim que o componente é montado. Como a operação de buscar dados não afeta diretamente o layout da página, o useEffect é apropriado para isso.

useLayoutEffect: Por outro lado, o useLayoutEffect é síncrono e é acionado antes do navegador pintar a tela, assim que o layout é calculado, mas antes de qualquer elemento estar visível. Isso faz dele uma escolha mais adequada quando é necessário garantir que as operações tenham efeito imediato no layout da página. Este é o hook a ser escolhido se estiver lidando com operações sensíveis ao layout, como medições de elementos, manipulação direta do DOM ou animações que precisam ser aplicadas antes da renderização.

import React, { useLayoutEffect, useState, useRef } from 'react';

const ExampleComponent = () => {
  const [width, setWidth] = useState(0);
  const containerRef = useRef(null);

  useLayoutEffect(() => {
    // Função para medir a largura do elemento
    const measureWidth = () => {
      const elementWidth = containerRef.current.offsetWidth;
      setWidth(elementWidth);
    };

    // Medição da largura do elemento
    measureWidth(); 
    
    // Adicionando listener de resize
    window.addEventListener('resize', measureWidth); 
    
    return () => {
      // Removendo listener de resize
      window.removeEventListener('resize', measureWidth); 
    };
  }, []);

  return (
    <div ref={containerRef}>
      <p>Largura do elemento: {width}px</p>
    </div>
  );
};

export default ExampleComponent;

Exemplo de useLayoutEffect

Neste exemplo, o useLayoutEffect é utilizado para medir dinamicamente a largura de um elemento sempre que a janela for redimensionada. Como essa operação afeta diretamente o layout da página, o useLayoutEffect é a escolha apropriada.

Quando Utilizar Cada Um?

  • useEffect: Utilize quando a operação não afeta diretamente o layout da página e pode ser executada de forma assíncrona.
  • useLayoutEffect: Escolha este quando precisar garantir que as operações tenham efeito imediato no layout da página.

Em resumo, a escolha entre useEffect e useLayoutEffect depende da natureza da tarefa que está sendo realizada. Ambos são ferramentas valiosas em diferentes cenários, e entender suas diferenças é fundamental para tomar as melhores decisões ao lidar com efeitos colaterais em seus componentes React.