Skip to main content

useLayoutEffect

Este hook é pouco utilizado mas muito poderoso, pode trazer grandes vantagens para aplicações, principalmente aquelas que atuam com troca de tema e modificações de layout que é muito dos casos de aplicações SaaS.

O hook useLayoutEffect é bem parecido com o useEffect, mas com uma diferença importante: ele é executado sincronamente após as mutações do DOM, mas antes que o navegador pinte a tela. Isso é útil quando você precisa fazer medições ou manipular o layout diretamente, garantindo que as mudanças aconteçam antes da renderização final.

Vamos ver isso com um exemplo prático onde manipulamos cores com base no tamanho de um elemento! 🎨

Corpo

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

function ColorBox() {
const [color, setColor] = useState('lightblue');
const boxRef = useRef(null);

// Função para determinar a cor com base na largura
const getColorByWidth = (width) => {
if (width < 200) return 'lightcoral';
if (width < 400) return 'lightgoldenrodyellow';
if (width < 600) return 'lightgreen';
return 'lightblue';
}

useLayoutEffect(() => {
const box = boxRef.current;

// Captura a largura da caixa e define a cor antes da renderização
if (box) {
const width = box.offsetWidth;
const newColor = getColorByWidth(width);
setColor(newColor);
}
}, [])

return (
<div
ref={boxRef}
style={{
width: '80%',
height: '200px',
backgroundColor: color,
margin: '20px auto',
border: '2px solid #333',
transition: 'background-color 0.3s ease',
}}
>
<h2 style={{ textAlign: 'center', paddingTop: '80px' }}>
Cor: {color.toUpperCase()}
</h2>
</div>
);
}

Como funciona?

No exemplo acima utilizei o useLayoutEffect para capturar a largura do box imediatamente após a mutação do DOM, mas antes que a cor de fato seja exibida.

O ref foi utilizado para acessar diretamente o elemento DOM e medir sua largura.

A estrutura básica do useLayoutEffect é a seguinte:

useLayoutEffect(() => {
// Código que manipula o DOM ou calcula layout
return () => {
// Cleanup (opcional)
}
}, [dependencias])

Outro exemplo aplicado a troca de tema:

useLayoutEffect
import React, { useState, useLayoutEffect } from "react";
import App from "./App";

function ApplyTheme() {
const [theme, setTheme] = useState("light");

useLayoutEffect(() => {
document.body.style.backgroundColor = theme === "light" ? "#fff" : "#000";
}, [theme]);

return <App />;
}

Por que usar useLayoutEffect?

Para fazer manipulações ou cálculos considerando o layout da aplicação ou de algum elemento (offset, scroll, dimensões). É também um hook importante para manipular diretamente o DOM antes da renderização final.

Garantir que o estado ou estilo seja atualizado imediatamente antes de pintar a tela.

Se você usasse useEffect no exemplo acima, veria uma piscada rápida de cor antes da atualização, porque ele roda depois da renderização. Com useLayoutEffect, a cor já vem ajustada antes de pintar a tela, deixando a experiência mais fluida! ✨

Já trabalhei com aplicações SaaS com troca de tema em tempo real e o hook utilizado para este fim foi o useLayoutEffect, que é o indicado para este caso. Com o useEffect teríamos um flick na tela, como mencionei anteriormente.

Dica

Se você não precisa manipular o DOM antes da renderização, prefira useEffect para evitar bloqueios desnecessários no desempenho.

tip

Conheça mais sobre os hooks em:

Referências: