<StrictMode>
<StrictMode>
permite que você encontre erros comuns em seus componentes mais cedo durante o desenvolvimento.
<StrictMode>
<App />
</StrictMode>
- Referência
- Uso
- Habilitando o Modo Estrito para todo o aplicativo
- Habilitando o Modo Estrito para uma parte do aplicativo
- Corrigindo erros encontrados por re-renderização em desenvolvimento
- Corrigindo erros encontrados ao re-executar Efeitos em desenvolvimento
- Corrigindo avisos de depreciação habilitados pelo Modo Estrito
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>
);
O Modo Estrito habilita os seguintes comportamentos apenas para desenvolvimento:
- Seus componentes serão re-renderizados uma vez a mais para encontrar erros causados por renderização impura.
- Seus componentes re-executarão efeitos uma vez a mais para encontrar erros causados pela ausência de limpeza de efeito.
- Seus componentes serão verificados quanto ao uso de APIs obsoletas.
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.
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:
- O corpo da função do seu componente (apenas a lógica de nível superior, portanto, isso não inclui código dentro de manipuladores de eventos)
- Funções que você passa para
useState
,set
functions,useMemo
, ouuseReducer
- Alguns métodos de componentes de classe, como
constructor
,render
,shouldComponentUpdate
(veja a lista completa)
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.
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:
findDOMNode
. Veja alternativas.- Métodos de ciclo de vida de classe
UNSAFE_
, comoUNSAFE_componentWillMount
. Veja alternativas. - Contexto legado (
childContextTypes
,contextTypes
, egetChildContext
). Veja alternativas. - Referências de string legado (
this.refs
). Veja alternativas.
Essas APIs são principalmente usadas em componentes de classe mais antigos, portanto, raramente aparecem em aplicativos modernos.