<StrictMode> permite que você encontre erros comuns em seus componentes mais cedo durante o desenvolvimento.

<StrictMode>
<App />
</StrictMode>

Referência

<StrictMode>

Use StrictMode para habilitar comportamentos e avisos adicionais de desenvolvimento para a árvore de componentes dentro:

import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';

const root = createRoot(document.getElementById('root'));
root.render(
<StrictMode>
<App />
</StrictMode>
);

Veja mais exemplos abaixo.

O Modo Estrito habilita os seguintes comportamentos apenas para desenvolvimento:

Props

StrictMode não aceita props.

Ressalvas

  • Não há como optar por sair do Modo Estrito dentro de uma árvore envolvida em <StrictMode>. Isso dá a você confiança de que todos os componentes dentro de <StrictMode> estão sendo verificados. Se duas equipes trabalhando em um produto discordarem sobre a validade das verificações, elas precisam chegar a um consenso ou mover <StrictMode> para baixo na árvore.

Uso

Habilitando o Modo Estrito para todo o aplicativo

O Modo Estrito habilita verificações adicionais apenas para desenvolvimento para toda a árvore de componentes dentro do componente <StrictMode>. Essas verificações ajudam você a encontrar erros comuns em seus componentes no início do processo de desenvolvimento.

Para habilitar o Modo Estrito para todo o seu aplicativo, envolva seu componente raiz com <StrictMode> ao renderizá-lo:

import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';

const root = createRoot(document.getElementById('root'));
root.render(
<StrictMode>
<App />
</StrictMode>
);

Recomendamos envolver todo o seu aplicativo no Modo Estrito, especialmente para aplicativos recém-criados. Se você usar uma biblioteca que chama createRoot por você, verifique sua documentação para saber como habilitar o Modo Estrito.

Embora as verificações do Modo Estrito executem apenas em desenvolvimento, elas ajudam você a encontrar erros que já existem em seu código, mas que podem ser difíceis de reproduzir de forma confiável em produção. O Modo Estrito permite que você corrija erros antes que seus usuários os relatem.

Note

O Modo Estrito habilita as seguintes verificações em desenvolvimento:

Todas essas verificações são apenas para desenvolvimento e não afetam a construção para produção.


Habilitando o Modo Estrito para uma parte do aplicativo

Você também pode habilitar o Modo Estrito para qualquer parte de sua aplicação:

import { StrictMode } from 'react';

function App() {
return (
<>
<Header />
<StrictMode>
<main>
<Sidebar />
<Content />
</main>
</StrictMode>
<Footer />
</>
);
}

Neste exemplo, as verificações do Modo Estrito não serão executadas contra os componentes Header e Footer. No entanto, elas serão executadas em Sidebar e Content, bem como todos os componentes dentro deles, não importa quão profundos sejam.


Corrigindo erros encontrados por re-renderização em desenvolvimento

O React assume que cada componente que você escreve é uma função pura. Isso significa que os componentes React que você escreve devem sempre retornar o mesmo JSX dadas as mesmas entradas (props, estado e contexto).

Componentes que quebram essa regra se comportam de forma imprevisível e causam erros. Para ajudar você a encontrar acidentalmente código impuro, o Modo Estrito chama algumas de suas funções (apenas aquelas que deveriam ser puras) duas vezes em desenvolvimento. Isso inclui:

Se uma função for pura, executá-la duas vezes não altera seu comportamento porque uma função pura produz o mesmo resultado toda vez. No entanto, se uma função for impura (por exemplo, se ela muta os dados que recebe), executá-la duas vezes tende a ser notável (é isso que a torna impura!) Isso ajuda você a identificar e corrigir o erro mais cedo.

Aqui está um exemplo para ilustrar como a re-renderização no Modo Estrito ajuda você a encontrar erros mais cedo.

Este componente StoryTray recebe um array de stories e adiciona um último item “Criar História” no final:

export default function StoryTray({ stories }) {
  const items = stories;
  items.push({ id: 'create', label: 'Criar História' });
  return (
    <ul>
      {items.map(story => (
        <li key={story.id}>
          {story.label}
        </li>
      ))}
    </ul>
  );
}

Há um erro no código acima. No entanto, é fácil perder, pois a saída inicial parece correta.

Este erro se tornará mais perceptível se o componente StoryTray for re-renderizado várias vezes. Por exemplo, vamos fazer com que o StoryTray seja re-renderizado com uma cor de fundo diferente sempre que você passar o mouse sobre ele:

import { useState } from 'react';

export default function StoryTray({ stories }) {
  const [isHover, setIsHover] = useState(false);
  const items = stories;
  items.push({ id: 'create', label: 'Criar História' });
  return (
    <ul
      onPointerEnter={() => setIsHover(true)}
      onPointerLeave={() => setIsHover(false)}
      style={{
        backgroundColor: isHover ? '#ddd' : '#fff'
      }}
    >
      {items.map(story => (
        <li key={story.id}>
          {story.label}
        </li>
      ))}
    </ul>
  );
}

Observe como cada vez que você passa o mouse sobre o componente StoryTray, “Criar História” é adicionado à lista novamente. A intenção do código era adicioná-lo uma única vez ao final. Mas o StoryTray modifica diretamente o array stories a partir das props. Cada vez que o StoryTray é renderizado, ele adiciona “Criar História” novamente ao final do mesmo array. Em outras palavras, o StoryTray não é uma função pura — executá-lo várias vezes produz resultados diferentes.

Para corrigir esse problema, você pode fazer uma cópia do array e modificar essa cópia em vez do original:

export default function StoryTray({ stories }) {
const items = stories.slice(); // Clona o array
// ✅ Bom: Adicionando a um novo array
items.push({ id: 'create', label: 'Criar História' });

Isso tornaria a função StoryTray pura. Cada vez que é chamada, ela apenas modificaria uma nova cópia do array e não afetaria nenhum objeto ou variável externa. Isso resolve o erro, mas você teve que fazer o componente re-renderizar mais vezes antes que ficasse óbvio que algo estava errado com seu comportamento.

No exemplo original, o erro não era óbvio. Agora, vamos envolver o código original (com erro) em <StrictMode>:

export default function StoryTray({ stories }) {
  const items = stories;
  items.push({ id: 'create', label: 'Criar História' });
  return (
    <ul>
      {items.map(story => (
        <li key={story.id}>
          {story.label}
        </li>
      ))}
    </ul>
  );
}

O Modo Estrito sempre chama sua função de renderização duas vezes, então você pode ver o erro imediatamente (“Criar História” aparece duas vezes). Isso permite que você perceba tais erros cedo no processo. Quando você corrige seu componente para renderizar no Modo Estrito, você também corrige muitos possíveis erros futuros de produção, como a funcionalidade de hover mencionada anteriormente:

import { useState } from 'react';

export default function StoryTray({ stories }) {
  const [isHover, setIsHover] = useState(false);
  const items = stories.slice(); // Clona o array
  items.push({ id: 'create', label: 'Criar História' });
  return (
    <ul
      onPointerEnter={() => setIsHover(true)}
      onPointerLeave={() => setIsHover(false)}
      style={{
        backgroundColor: isHover ? '#ddd' : '#fff'
      }}
    >
      {items.map(story => (
        <li key={story.id}>
          {story.label}
        </li>
      ))}
    </ul>
  );
}

Sem o Modo Estrito, era fácil perder o erro até que você adicionasse mais re-renderizações. O Modo Estrito fez o mesmo erro aparecer imediatamente. O Modo Estrito ajuda você a encontrar erros antes de enviá-los para sua equipe e para seus usuários.

Leia mais sobre como manter os componentes puros.

Note

Se você tem React DevTools instalado, qualquer chamada console.log durante a segunda chamada de renderização aparecerá ligeiramente atenuada. O React DevTools também oferece uma configuração (desativada por padrão) para suprimir completamente essas chamadas.


Corrigindo erros encontrados ao re-executar Efeitos em desenvolvimento

O Modo Estrito também pode ajudar a encontrar erros em Efeitos.

Todo Efeito tem algum código de configuração e pode ter algum código de limpeza. Normalmente, o React chama a configuração quando o componente monta (é adicionado à tela) e chama a limpeza quando o componente desmonta (é removido da tela). O React então chama a limpeza e a configuração novamente se suas dependências mudaram desde a última renderização.

Quando o Modo Estrito está ativo, o React também executará um ciclo extra de configuração+limpeza no desenvolvimento para cada Efeito. Isso pode parecer surpreendente, mas ajuda a revelar erros sutis que são difíceis de pegar manualmente.

Aqui está um exemplo para ilustrar como a re-execução de Efeitos no Modo Estrito ajuda você a encontrar erros mais cedo.

Considere este exemplo que conecta um componente a um chat:

import { createRoot } from 'react-dom/client';
import './styles.css';

import App from './App';

const root = createRoot(document.getElementById("root"));
root.render(<App />);

Há um problema com este código, mas pode não ser imediatamente claro.

Para tornar o problema mais óbvio, vamos implementar um recurso. No exemplo abaixo, roomId não está codificado. Em vez disso, o usuário pode selecionar o roomId que deseja conectar a partir de um dropdown. Clique em “Abrir chat” e então selecione diferentes salas de chat uma a uma. Mantenha controle do número de conexões ativas no console:

import { createRoot } from 'react-dom/client';
import './styles.css';

import App from './App';

const root = createRoot(document.getElementById("root"));
root.render(<App />);

Você notará que o número de conexões abertas sempre continua aumentando. Em um aplicativo real, isso causaria problemas de desempenho e rede. O problema é que seu Efeito está faltando uma função de limpeza:

useEffect(() => {
const connection = createConnection(serverUrl, roomId);
connection.connect();
return () => connection.disconnect();
}, [roomId]);

Agora que seu Efeito “limpa” após si mesmo e destrói as conexões desatualizadas, o vazamento está resolvido. No entanto, note que o problema não se tornou visível até que você adicionasse mais recursos (a caixa de seleção).

No exemplo original, o erro não era óbvio. Agora vamos envolver o código original (bugado) em <StrictMode>:

import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import './styles.css';

import App from './App';

const root = createRoot(document.getElementById("root"));
root.render(
  <StrictMode>
    <App />
  </StrictMode>
);

Com o Modo Estrito, você imediatamente vê que há um problema (o número de conexões ativas salta para 2). O Modo Estrito executa um ciclo extra de configuração+limpeza para cada Efeito. Esse Efeito não tem lógica de limpeza, então cria uma conexão extra, mas não a destrói. Isso serve como um sinal de que você está perdendo uma função de limpeza.

O Modo Estrito permite que você perceba tais erros cedo no processo. Quando você corrige seu Efeito adicionando uma função de limpeza no Modo Estrito, você também corrige muitos possíveis erros futuros de produção, como a caixa de seleção mencionada anteriormente:

import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import './styles.css';

import App from './App';

const root = createRoot(document.getElementById("root"));
root.render(
  <StrictMode>
    <App />
  </StrictMode>
);

Observe como a contagem de conexões ativas no console não continua crescendo.

Sem o Modo Estrito, era fácil perder que seu Efeito precisava de limpeza. Ao executar configuração → limpeza → configuração em vez de apenas configuração para seu Efeito no desenvolvimento, o Modo Estrito tornou a lógica de limpeza ausente mais perceptível.

Leia mais sobre como implementar a limpeza de Efeitos.


Corrigindo avisos de depreciação habilitados pelo Modo Estrito

O React avisa se algum componente em algum lugar dentro de uma árvore <StrictMode> usa uma dessas APIs obsoletas:

Essas APIs são principalmente usadas em componentes de classe mais antigos, portanto, raramente aparecem em aplicativos modernos.