Ordem de execução dos Hooks


A ordem de execução dos Hooks no React é um conceito fundamental para entender como os diferentes Hooks interagem durante o ciclo de vida de um componente. Os Hooks são funções especiais fornecidas pelo React que permitem aos desenvolvedores utilizar estados, efeitos e outras funcionalidades em componentes funcionais.

Para entender a ordem de execução dos Hooks, podemos dividi-lo em etapas distintas e observar como cada parte contribui para o ciclo de vida do componente. As etapas incluem:

1. Run Lazy Initializers

A primeira etapa ocorre quando o componente é inicializado e os lazy initializers são executados. Neste caso, o useState é utilizado para criar o estado state1 com um lazy initializer, que é uma função que fornece o valor inicial do estado. No exemplo, o lazy initializer é uma função que retorna a data formatada como uma string. Esse valor é então exibido no console.

// Lazy Initializer
const [state1, setState1] = useState(() => {
  const state = new Date().toLocaleDateString();
  console.log('%cState Lazy initializer - (useState + InitialValue) = ' + state, 'color: green');
  return state;
});

2. Render

A segunda etapa é a renderização do componente, onde os elementos JSX são criados e o componente é exibido na tela. No caso, a função ReactHooks é chamada dentro do componente Home quando o estado show é true.

return (
  <div>
    <p style={{ fontSize: '60px' }} onClick={() => setShow((s) => !s)}>
      Show hooks
    </p>
    {show && <ReactHooks />}
  </div>
);

3. React Updates DOM

Nesta etapa, o React atualiza o DOM para refletir as alterações feitas durante a renderização. Isso inclui a atualização de elementos na tela.

4. Cleanup LayoutEffects

Antes de realizar o layout no DOM, o React executa as funções de cleanup associadas aos useLayoutEffect. No exemplo, isso é exibido no console:

useLayoutEffect(() => {
  console.log('%cuseLayoutEffect (Cleanup)', 'color: #e61a4d');
 
  return () => {
    console.log('%cuseLayoutEffect (Cleanup)', 'color: #e61a4d');
  };
});

5. Run LayoutEffects

Após o cleanup, as funções de useLayoutEffect são executadas. No exemplo, isso é exibido no console:

useLayoutEffect(() => {
  console.log('%cuseLayoutEffect', 'color: #e61a4d');
 
  return () => {
    console.log('%cuseLayoutEffect (Cleanup)', 'color: #e61a4d');
  };
});

6. Browser Paints Screen

Nesta etapa, o navegador pinta a tela para refletir as mudanças feitas durante o layout.

7. Cleanup Effects

Antes de realizar o useEffect, as funções de cleanup associadas a eles são executadas. Isso inclui os efeitos sem dependências e aqueles com dependências vazias.

useEffect(() => {
  console.log('%cuseEffect (Cleanup) -> No Dependencies', 'color: #dbc70f');
 
  return () => {
    console.log('%cuseEffect (Cleanup) -> No Dependencies', 'color: #dbc70f');
  };
});
 
useEffect(() => {
  console.log('%cuseEffect (Cleanup) -> Empty dependencies', 'color: #dbc70f');
 
  return () => {
    console.log('%cuseEffect (Cleanup) -> Empty dependencies', 'color: #dbc70f');
  };
}, []);

8. Run Effects

Finalmente, as funções de efeito (useEffect) são executadas. Isso inclui os efeitos com e sem dependências.

useEffect(() => {
  console.log('%cuseEffect -> No Dependencies', 'color: #dbc70f');
  renders.current += 1;
 
  return () => {
    console.log('%cuseEffect (Cleanup) -> No Dependencies', 'color: #dbc70f');
  };
});
 
useEffect(() => {
  const listener = () => console.log('Listener...');
  console.log('%cuseEffect -> Empty dependencies', 'color: #dbc70f');
 
  return () => {
    console.log('%cuseEffect (Cleanup) -> Empty dependencies', 'color: #dbc70f');
  };
}, []);

Em resumo, o ciclo de vida do componente com Hooks passam por várias etapas, incluindo a execução de inicializadores lazy, renderização, atualização do DOM, cleanup e execução de efeitos, culminando no ajuste final da tela pelo navegador. Isso demonstra como os Hooks são coordenados e como suas fases são integradas no fluxo geral do ciclo de vida do componente.

Referências