Telles Logo
Ver todos os artigos

nov 16, 2022
·
views
·
likes

O que acontece com o StrictMode no React?

Já se perguntou o que acontece com o StrictMode no React? Nesse artigo vamos explorar o que é o StrictMode, como ele funciona e por que é útil para o desenvolvimento de aplicativos React.

No React, o StrictMode tem um comportamento feito para garantir que seja compatível com o estado reutilizável.

Quando o StrictMode está ativo (com a tag), o React chama efeitos de atualização dupla (montar -> desmontar -> montar) para componentes recém-montados. Isso é feito para garantir que o componente seja resiliente a ser "montado" e "desmontado" mais de uma vez.

Assim como outros comportamentos de StrictMode, o React só faz isso para compilações em modo desenvolvimento.

Vamos ver o exemplo abaixo:

import { useEffect, useLayoutEffect } from "react";
 
export default function App() {
  useEffect(() => {
    console.log("useEffect: O efeito é executado");

    return () => {
      console.log("useEffect: Limpa o código executado");
    };
  }, []);

  useLayoutEffect(() => {
    console.log("useLayout: O efeito é executado");

    return () => {
      console.log("useLayout: Limpa o código executado");
    };
  }, []);

  console.log("Render dos componentes");

  return <h1>StrictMode Effects no React</h1>;
}

O componente <App /> acima declara alguns efeitos para serem executados na montagem e desmontagem. Antes do React 18, as funções de configuração executavam apenas uma vez (após o componente ser montado inicialmente) e as funções de limpeza também executavam apenas uma vez (após o componente ser desmontado).

No código acima o que acontece o seguinte:

  1. React renderiza o componente ( 2x )

  2. React monta o componente

  3. O código de configuração do efeito de layout é executado

  4. O código de configuração do efeito é executado

  5. React simula o componente sendo escondido ou desmontado

  6. O código de limpeza do efeito de layout é executado

  7. O código de limpeza do efeito é executado

  8. React simula o componente sendo mostrado novamente ou remontado

  9. O código de configuração do efeito de layout é executado

  10. O código de configuração do efeito é executado

Quando os componentes são encapsulados StrictMode, o React executa certas funções duas vezes para ajudar os desenvolvedores a detectar erros em seu código.

Como o StrictMode pode ser útil?

Vamos ver um exemplo em que o StrictMode nos ajuda a encontrar um erro grave.

  import { StrictMode, useState } from "react";
  import { createRoot } from "react-dom/client";
  
  const courseData = [
    { id: 1, title: "NodeJS", isActive: true },
    { id: 2, title: "React", isActive: false }
  ];
  
  export default function App() {
    const [courseList, setCheck] = useState(courseData);
  
    const handleActiveCourse = (courseId) => {
      setCheck((prevState) => {
        console.log(JSON.stringify(prevState));
  
        return prevState.map((course) => {
          if (course.id === courseId) {
            course.isActive = !course.isActive; // Mutação feita aqui
          }
  
          return course;
        });
      });
    };
  
    return (
      <ul>
        {courseList.map((course) => (
          <li key={course.id}>
            <span
              style={{
                color: course.isActive ? "green" : "gray"
              }}
            >
              {course.title}
            </span>
            <button onClick={() => handleActiveCourse(course.id)}>
              Marcar como {course.isActive ? "Inativo" : "Ativo"}
            </button>
          </li>
        ))}
      </ul>
    );
  }
  
  const rootElement = document.getElementById("root");
  const root = createRoot(rootElement);
  
  root.render(
    <StrictMode>
      <App />
    </StrictMode>
  );

Mas qual é o problema com o exemplo acima?

Você deve ter notado que os botões não funcionam como esperado, eles não alternam o isActive de truepara falsesempre que clicamos nele e o problema é que a função de atualização passada para o setChecked() é uma função pura, e ela altera um objeto no estado. Como a função está sendo chamada duas vezes e não é uma função pura, na nossa segunda chamada ela reverte o booleano de volta ao seu valor original.

E só devido à invocação dupla do StrictMode que nós conseguimos encontrar esse erro. Se removermos o StrictMode, o componente funcionaria como desejado, mas isso não significa que o código foi criado corretamente, ele só funciona devido ao quão isolado é o componente e, em cenários reais, mutações como essas podem causar sérios problemas.

Se você alterar a função para uma função pura, ele resolverá o problema, basta alterar o trecho de código da linha 13 para este abaixo:

setCheck((prevState) => 
	        return prevState.map((course) =>
	          course.id === courseId ? { ...course, isActive: !course.isActive } : course);
	)

O StrictMode nos facilita no desenvolvimento para evitar erros de programação, onde ele nos ajuda a validar o tempo de execução de cada alteração de estado.

Esse conteúdo e outros conteúdos avançados de React você encontra no Curso React para Unicórnios nesse link!