Existe uma abordagem sistemática para depurar o que está fazendo com que um componente seja renderizado novamente no React? Coloquei um console.log () simples para ver quanto tempo ele renderiza, mas estou tendo problemas para descobrir o que está causando o componente renderizar várias vezes, ou seja, (4 vezes) no meu caso. Existe uma ferramenta que mostra uma linha do tempo e / ou todos os processamentos e pedidos da árvore de componentes?
156
shouldComponentUpdate
para desativar a atualização automática de componentes e iniciar o rastreamento a partir daí. Mais informações podem ser encontradas aqui: facebook.github.io/react/docs/optimizing-performance.htmlRespostas:
Se você quiser um pequeno trecho sem nenhuma dependência externa, acho útil
Aqui está um pequeno gancho que eu uso para rastrear atualizações dos componentes funcionais
fonte
setState
método (em um componente de classe) porsetState(...args) { super.setState(...args) }
e, em seguida, definir um ponto de interrupção no depurador, que poderá para rastrear de volta para a função que define o estado.useTraceUpdate
depois de defini-lo como você o escreveu?function MyComponent(props) { useTraceUpdate(props); }
e ele irá registrar sempre que adereços mudançasthis.state
é indefinido.Aqui estão algumas instâncias em que um componente React será renderizado novamente.
this.setState()
dentro do componente. Isso irá provocar os seguintes métodos de componentes de ciclo de vidashouldComponentUpdate
>componentWillUpdate
>render
>componentDidUpdate
props
. Esse gatilho vontadecomponentWillReceiveProps
>shouldComponentUpdate
>componentWillUpdate
>render
>componentDidUpdate
(connect
método dereact-redux
gatilho isso quando há mudanças aplicáveis na loja Redux)this.forceUpdate
que é semelhante athis.setState
Você pode minimizar o renderizador do seu componente implementando uma verificação dentro do seu
shouldComponentUpdate
e retornandofalse
se não for necessário.Outra maneira é usar
React.PureComponent
ou componentes sem estado. Os componentes puros e sem estado são renderizados novamente somente quando houver alterações nos acessórios.fonte
shouldComponentUpdate
, ou estenderReact.PureComponent
, para aplicar somente a nova renderização nas alterações.const MyComponent = (props) => <h1>Hello {props.name}</h1>;
(esse é um componente sem estado). Ele será renderizado novamente quando o componente pai for renderizado novamente.A resposta do @ jpdelatorre é ótima para destacar razões gerais pelas quais um componente React pode ser renderizado novamente.
Eu só queria mergulhar um pouco mais fundo em uma instância: quando os objetos mudam . A solução de problemas do que está causando a re-renderização de um componente React é um problema comum e, na minha experiência, muitas vezes rastrear esse problema envolve determinar quais objetos estão sendo alterados .
Os componentes de reação são renderizados novamente quando recebem novos adereços. Eles podem receber novos adereços como:
<MyComponent prop1={currentPosition} prop2={myVariable} />
ou se
MyComponent
estiver conectado a uma loja redux:Sempre que o valor de
prop1
,prop2
,prop3
, ouprop4
mudançasMyComponent
vai voltar a render. Com 4 adereços, não é muito difícil rastrear quais adereços estão sendo alterados colocando umconsole.log(this.props)
no início dorender
bloco. No entanto, com componentes mais complicados e mais e mais adereços, esse método é insustentável.Aqui está uma abordagem útil (usando o lodash por conveniência) para determinar quais alterações de prop estão causando a re-renderização de um componente:
A adição desse snippet ao seu componente pode ajudar a revelar o culpado que está causando as renderizações duvidosas e, muitas vezes, isso ajuda a esclarecer os dados desnecessários sendo canalizados para os componentes.
fonte
UNSAFE_componentWillReceiveProps(nextProps)
e está obsoleto. "Este ciclo de vida foi nomeado anteriormentecomponentWillReceiveProps
. Esse nome continuará funcionando até a versão 17." Na documentação do React .Estranho, ninguém deu essa resposta, mas eu a acho muito útil, principalmente porque as mudanças nos objetos estão quase sempre profundamente aninhadas.
Hooks fanboys:
Fanboys "velhos" da escola:
PS: Eu ainda prefiro usar HOC (componente de ordem superior) porque às vezes você destrói seus adereços no topo e a solução de Jacob não se encaixa bem
Isenção de responsabilidade: nenhuma afiliação com o proprietário do pacote. Basta clicar em dezenas de vezes para tentar identificar a diferença em objetos profundamente aninhados.
fonte
Agora existe um gancho para isso disponível no npm:
https://www.npmjs.com/package/use-trace-update
(Divulgação, publiquei) Atualização: Desenvolvida com base no código de Jacob Rask
fonte
Usando ganchos e componentes funcionais, não apenas a mudança de suporte pode causar uma nova renderização. O que comecei a usar é um log bastante manual. Eu me ajudei muito. Você pode achar útil também.
Eu colo esta parte no arquivo do componente:
No início do método, mantenho uma referência ao WeakMap:
Depois de cada chamada "suspeita" (adereços, ganchos), escrevo:
fonte
As respostas acima são muito úteis, caso alguém esteja procurando um método específico para detectar a causa do novo renderizador, achei essa biblioteca redux-logger muito útil.
O que você pode fazer é adicionar a biblioteca e ativar a diferença entre os estados (existe nos documentos), como:
E adicione o middleware na loja.
Em seguida, coloque um
console.log()
na função de renderização do componente que você deseja testar.Em seguida, você pode executar o aplicativo e verificar os logs do console. Sempre que houver um log antes de mostrar a diferença entre o estado
(nextProps and this.props)
e você pode decidir se a renderização é realmente necessária láSerá semelhante à imagem acima, juntamente com a tecla diff.
fonte