¿Reacciona React todos los componentes y subcomponentes cada vez que setState
se llama?
Si es así, ¿por qué? Pensé que la idea era que React solo representaba tan poco como fuera necesario, cuando el estado cambiaba.
En el siguiente ejemplo simple, ambas clases se renderizan nuevamente cuando se hace clic en el texto, a pesar de que el estado no cambia en los clics posteriores, ya que el controlador onClick siempre establece state
el mismo valor:
this.setState({'test':'me'});
Hubiera esperado que los renders solo ocurrieran si los state
datos hubieran cambiado.
Aquí está el código del ejemplo, como un JS Fiddle y un fragmento incrustado:
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
fuente
fuente
setState()
incluso con datos ficticios hace que el elemento se represente de manera diferente, por lo que diría que sí. ¡Absolutamente debería intentar volver a renderizar su objeto cuando algo podría haber cambiado porque de lo contrario su demostración, suponiendo que fuera el comportamiento previsto, no funcionaría!shouldComponentUpdate
método, que supuse que una versión simple de él ya debe estar incluida en React. Parece que la versión predeterminada incluida en react simplemente devuelvetrue
, lo que obliga al componente a volver a renderizarse cada vez.Respuestas:
Por defecto, sí.
Hay un método booleano shouldComponentUpdate (objeto nextProps, objeto nextState) , cada componente tiene este método y es responsable de determinar "¿debería actualizar el componente (ejecutar la función de renderizado )?" cada vez que cambia de estado o pasa nuevos accesorios del componente principal.
Puede escribir su propia implementación del método shouldComponentUpdate para su componente, pero la implementación predeterminada siempre devuelve verdadero, lo que significa que siempre vuelve a ejecutar la función de representación.
Cita de documentos oficiales http://facebook.github.io/react/docs/component-specs.html#updating-shouldcomponentupdate
Siguiente parte de tu pregunta:
Hay dos pasos de lo que podemos llamar "render":
Renders virtuales DOM: cuando se llama al método de renderizado , devuelve una nueva estructura dom virtual del componente. Como mencioné antes, este método de representación se llama siempre cuando se llama a setState () , porque shouldComponentUpdate siempre devuelve verdadero por defecto. Entonces, por defecto, no hay optimización aquí en React.
Representaciones nativas de DOM: React cambia los nodos DOM reales en su navegador solo si se modificaron en el DOM virtual y tan poco como sea necesario: esta es la gran característica de React que optimiza la mutación DOM real y hace que React sea rápido.
fuente
setState
si detecta que hay una diferencia. Si es así, ¿cómo hacer esto mejor? ¿Comparar las cadenas json, construir y comparar hashes de objetos, ...?No, React no procesa todo cuando el estado cambia.
Cada vez que un componente está sucio (su estado cambió), ese componente y sus elementos secundarios se vuelven a representar. Esto, en cierta medida, es volver a renderizar lo menos posible. El único momento en que no se llama render es cuando alguna rama se mueve a otra raíz, donde teóricamente no necesitamos volver a renderizar nada. En su ejemplo,
TimeInChild
es un componente secundario deMain
, por lo que también se vuelve a representar cuando el estado de losMain
cambios.Reaccionar no compara los datos del estado. Cuando
setState
se llama, marca el componente como sucio (lo que significa que debe volver a procesarse). Lo importante a tener en cuenta es que, aunquerender
se llama al método del componente, el DOM real solo se actualiza si la salida es diferente del árbol DOM actual (también conocido como diferencia entre el árbol DOM virtual y el árbol DOM del documento). En su ejemplo, a pesar de que losstate
datos no han cambiado, la hora del último cambio sí lo hizo, haciendo que el DOM virtual sea diferente del DOM del documento, por lo tanto, el HTML se actualiza.fuente
render()
método sea "puro", independiente del estado externo.some branch is moved to another root
? ¿Cómo se llamabranch
? ¿Cómo se llamaroot
?what does it mean some branch is moved to another root? What do you call branch? What do you call root?
Aunque se indica en muchas de las otras respuestas aquí, el componente debería:
implementar
shouldComponentUpdate
para renderizar solo cuando el estado o las propiedades cambiencambie a extender un PureComponent , que ya implementa
shouldComponentUpdate
internamente un método para comparaciones superficiales.Aquí hay un ejemplo que utiliza
shouldComponentUpdate
, que funciona solo para este caso de uso simple y con fines de demostración. Cuando se usa esto, el componente ya no se vuelve a representar en cada clic, y se representa cuando se muestra por primera vez, y después de hacer clic una vez.fuente
Si. Llama al método render () cada vez que llamamos a setState cuando "shouldComponentUpdate" devuelve falso.
fuente
Otra razón para la "actualización perdida" puede ser la siguiente:
Si es el problema, entonces U puede evitar establecer el estado durante la actualización, debe verificar el valor del parámetro de estado de esta manera
Otra solución es agregar una propiedad inicializada al estado y configurarla por primera vez (si el estado se inicializa a un valor no nulo).
fuente
No todos los componentes.
el
state
componente de entrada se parece a la fuente de la cascada de estado de toda la aplicación.Entonces, el cambio ocurre desde donde llamó setState. El árbol de
renders
entonces se llama desde allí. Si ha utilizado un componente puro,render
se omitirá el.fuente