O React renderiza novamente todos os componentes e subcomponentes sempre que setState
é chamado?
Se sim, por quê? Eu pensei que a idéia era que o React renderizasse apenas o necessário - quando o estado mudou.
No exemplo simples a seguir, as duas classes são renderizadas novamente quando o texto é clicado, apesar do estado não ser alterado nos cliques subsequentes, pois o manipulador onClick sempre define state
o mesmo valor:
this.setState({'test':'me'});
Eu esperava que as renderizações só acontecessem se os state
dados tivessem mudado.
Aqui está o código do exemplo, como um JS Fiddle , e um snippet incorporado:
var TimeInChild = React.createClass({
render: function() {
var t = new Date().getTime();
return (
<p>Time in child:{t}</p>
);
}
});
var Main = React.createClass({
onTest: function() {
this.setState({'test':'me'});
},
render: function() {
var currentTime = new Date().getTime();
return (
<div onClick={this.onTest}>
<p>Time in main:{currentTime}</p>
<p>Click me to update time</p>
<TimeInChild/>
</div>
);
}
});
ReactDOM.render(<Main/>, document.body);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.0/react-dom.min.js"></script>
[1]: http://jsfiddle.net/fp2tncmb/2/
javascript
reactjs
Brad Parks
fonte
fonte
setState()
mesmo com dados fictícios faz com que o elemento seja renderizado de maneira diferente, então eu diria que sim. Absolutamente, ele deve tentar renderizar novamente seu objeto quando algo puder ter mudado, porque, caso contrário, sua demonstração - assumindo que era o comportamento pretendido - não funcionaria!shouldComponentUpdate
método, que eu assumi que uma versão simples dele já deve estar incluída no próprio React. Parece que a versão padrão incluída no react simplesmente retornatrue
- o que força o componente a renderizar novamente a cada vez.Respostas:
Por padrão - sim.
Existe um método booleano shouldComponentUpdate (objeto nextProps, objeto nextState) , cada componente possui esse método e é responsável por determinar "o componente deve atualizar (executar a função de renderização )?" toda vez que você muda de estado ou passa novos adereços do componente pai.
Você pode escrever sua própria implementação do método shouldComponentUpdate para seu componente, mas a implementação padrão sempre retorna true - ou seja, sempre executa novamente a função de renderização.
Citação de documentos oficiais http://facebook.github.io/react/docs/component-specs.html#updating-shouldcomponentupdate
Próxima parte da sua pergunta:
Existem duas etapas do que podemos chamar de "render":
Renderizações do DOM virtual: quando o método de renderização é chamado, ele retorna uma nova estrutura de dom virtual do componente. Como mencionei antes, esse método de renderização é chamado sempre quando você chama setState () , porque shouldComponentUpdate sempre retorna true por padrão. Portanto, por padrão, não há otimização aqui no React.
Renderizações nativas do DOM: o React altera os nós DOM reais no seu navegador apenas se eles foram alterados no Virtual DOM e o mínimo necessário - esse é o ótimo recurso do React que otimiza a mutação do DOM real e torna o React rápido.
fonte
setState
se detectar que há uma diferença? Se sim, como fazer isso da melhor maneira - compare as seqüências de caracteres json, construa e compare hashes de objetos, ...?Não, o React não processa tudo quando o estado muda.
Sempre que um componente está sujo (seu estado é alterado), esse componente e seus filhos são renderizados novamente. Isso, em certa medida, é re-renderizar o mínimo possível. O único momento em que a renderização não é chamada é quando algum ramo é movido para outra raiz, onde teoricamente não precisamos renderizar novamente. No seu exemplo,
TimeInChild
é um componente filho deMain
, portanto, também é renderizado novamente quando o estado dasMain
alterações.React não compara dados de estado. Quando
setState
é chamado, ele marca o componente como sujo (o que significa que ele precisa ser renderizado novamente). O importante a ser observado é que, embora orender
método do componente seja chamado, o DOM real é atualizado apenas se a saída for diferente da árvore DOM atual (também conhecida como difração entre a árvore DOM Virtual e a árvore DOM do documento). No seu exemplo, mesmo que osstate
dados não tenham sido alterados, a hora da última alteração foi alterada, tornando o DOM Virtual diferente do DOM do documento, portanto, por que o HTML é atualizado.fonte
render()
método fosse "puro" - independente do estado externo.some branch is moved to another root
? Como você chamabranch
? Como você chamaroot
?what does it mean some branch is moved to another root? What do you call branch? What do you call root?
Embora seja declarado em muitas das outras respostas aqui, o componente deve:
implementar
shouldComponentUpdate
para renderizar apenas quando o estado ou as propriedades mudamalterne para estender um PureComponent , que já implementa um
shouldComponentUpdate
método internamente para comparações superficiais.Aqui está um exemplo que usa
shouldComponentUpdate
, que funciona apenas para esse caso de uso simples e para fins de demonstração. Quando isso é usado, o componente não se reproduz novamente a cada clique e é renderizado quando exibido pela primeira vez e depois de ser clicado uma vez.fonte
Sim. Ele chama o método render () toda vez que chamamos setState, quando "shouldComponentUpdate" retorna false.
fonte
Outro motivo para "atualização perdida" pode ser o seguinte:
Se for o problema, então U pode evitar definir o estado durante a atualização, verifique o valor do parâmetro state como este
Outra solução é adicionar uma propriedade inicializada ao estado e configurá-la na primeira vez (se o estado for inicializado com um valor não nulo).
fonte
Nem todos os componentes.
o
state
componente in se parece com a fonte da cachoeira do estado de todo o aplicativo.Portanto, a mudança acontece de onde o setState chamou. A árvore
renders
então é chamada a partir daí. Se você usou componente puro, orender
será ignorado.fonte