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:
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.