Esto puede estar pisando esa línea entre responsable y obstinado, pero estoy yendo y viniendo sobre cómo estructurar un componente ReactJS a medida que crece la complejidad y podría usar alguna dirección.
Viniendo de AngularJS, quiero pasar mi modelo al componente como una propiedad y hacer que el componente modifique el modelo directamente. ¿O debería dividir el modelo en varias state
propiedades y volver a compilarlo cuando lo envíe de nuevo? ¿Cuál es la forma ReactJS?
Tome el ejemplo de un editor de publicaciones de blog. Intentar modificar el modelo directamente termina pareciéndose a:
var PostEditor = React.createClass({
updateText: function(e) {
var text = e.target.value;
this.props.post.text = text;
this.forceUpdate();
},
render: function() {
return (
<input value={this.props.post.text} onChange={this.updateText}/>
<button onClick={this.props.post.save}/>Save</button>
);
}
});
Lo que parece mal.
¿Es más la forma de reaccionar para hacer que nuestro text
modelo sea propiedad state
y compilarlo nuevamente en el modelo antes de guardarlo como:
var PostEditor = React.createClass({
getInitialState: function() {
return {
text: ""
};
},
componentWillMount: function() {
this.setState({
text: this.props.post.text
});
},
updateText: function(e) {
this.setState({
text: e.target.value
});
},
savePost: function() {
this.props.post.text = this.state.text;
this.props.post.save();
},
render: function() {
return (
<input value={this.state.text} onChange={this.updateText}/>
<button onClick={this.savePost}/>Save</button>
);
}
});
Esto no requiere una llamada this.forceUpdate()
, pero a medida que el modelo crece, (una publicación puede tener un autor, un tema, etiquetas, comentarios, calificaciones, etc.) el componente comienza a complicarse mucho.
¿Es el primer método con ReactLink el camino a seguir?
text
campo, tenemos unsetText
método que valida y algunas otras cosas. Puedo ver que el método (2) funciona sisetText
es puro y devuelve una nueva instancia del modelo. Sin embargo, sisetText
solo actualiza el estado interno, aún deberíamos llamarforceUpdate
, ¿verdad?forceUpdate
, pero en ese momento estás "goteando" de React. Sería mejor pasar unasetState()
devolución de llamada al modelo opaco para evitar tener que activar manualmente los renders.Actualización 2016: React ha cambiado, y la explicación "accesorios vs estado" se volvió muy simple. Si un componente necesita cambiar datos, póngalo en un estado, de lo contrario en accesorios. Porque los accesorios son de solo lectura ahora.
¿Cuál es la diferencia exacta entre accesorios y estado?
Puedes encontrar una buena explicación aquí (versión completa)
fuente
setProps
está en desuso y no debe usarse. Reemplazar es volver a procesar el componente y dejar que React maneje las diferencias.De React doc
Desde TrySpace : cuando se actualizan los accesorios (o el estado) (a través de setProps / setState o parent), el componente también se vuelve a representar.
fuente
Una lectura de Thinking in React :
fuente
No estoy seguro de responder a su pregunta, pero descubrí que, especialmente en una aplicación grande / en crecimiento, el patrón Contenedor / Componente funciona increíblemente bien.
Esencialmente tienes dos componentes React:
Ejemplo
Nota: este ejemplo es probablemente demasiado simple para ilustrar los beneficios de este patrón, ya que es bastante detallado para un caso tan sencillo.
Beneficios
Al mantener separadas la lógica de visualización y la gestión de datos / estado, tiene un componente de visualización reutilizable que:
También tiene un componente contenedor que se ocupa de todas las comunicaciones externas. Esto debería hacer que sea más fácil ser flexible sobre la forma en que accede a sus datos si realiza cambios serios más adelante *.
Este patrón también hace que escribir e implementar pruebas unitarias sea mucho más sencillo.
Después de haber iterado una gran aplicación React varias veces, descubrí que este patrón mantiene las cosas relativamente indoloras, especialmente cuando tiene componentes más grandes con estilos calculados o interacciones DOM complicadas.
* Lea sobre el patrón de flujo y eche un vistazo a
Marty.js , que inspiró en gran medida esta respuesta (y he estado usando mucho últimamente)Redux (y react-redux ), que implementan este patrón extremadamente bien.fuente
Creo que estás usando un antipatrón que Facebook ya ha explicado en este enlace.
Esto es lo que estás encontrando:
La primera vez que se representa el componente interno, tendrá {foo: 'bar'} como valor de apoyo. Si el usuario hace clic en el ancla, el estado del componente principal se actualizará a {valor: {foo: 'barbar'}}, lo que desencadenará el proceso de representación del componente interno, que recibirá {foo: 'barbar'} como El nuevo valor para el accesorio.
El problema es que, dado que los componentes primarios y internos comparten una referencia al mismo objeto, cuando el objeto se muta en la línea 2 de la función onClick, cambiará la propiedad que tenía el componente interno. Entonces, cuando se inicia el proceso de renderizado y se invoca shouldComponentUpdate, this.props.value.foo será igual a nextProps.value.foo, porque de hecho, this.props.value hace referencia al mismo objeto que nextProps.value.
En consecuencia, dado que nos perderemos el cambio en la utilería y cortocircuitaremos el proceso de renderizado, la interfaz de usuario no se actualizará de 'bar' a 'barbar'
fuente
Innercomponents
código?