reactjs - used - ¿Es un buen diseño, cuando una tienda React Flux emite múltiples tipos de eventos?
toptal react interview questions (2)
El flujo como patrón de diseño se basa en la idea de que todos los datos residen en "tiendas". Cada tienda contiene datos para un dominio de información dado. Como ejemplo: en Flux, todos los comentarios residirían en un CommentStore.
Cuando se cambian los datos en una tienda, debe emitir un evento y todos los componentes que se construyen sobre este "dominio de información", deben reenviarse y mostrar los nuevos datos de dominio.
Descubrí que cuando una tienda emite varios tipos de eventos, es más probable que los componentes no escuchen ese evento específico, por lo que no se redirigen a sí mismos cuando se modifican los datos de los dominios.
Esto rompe todo el patrón de flujo y puede crear fácilmente errores difíciles de encontrar donde los componentes no están sincronizados con la información de las tiendas.
En su lugar, le recomendaría que diseñe sus componentes a partir de la "Ley de Demeter", ya que cada componente debe saber todo lo que necesita.
Entonces, en lugar de que el componente escuche un evento que dice "commentList se ha actualizado", debe crear un commentListComponent que escuche en un evento de una sola tienda. Por lo tanto, el componente escuchará en commentStore.on (''cambiar'') - Generalmente permito que todas las tiendas emitan un evento de ''cambio''. Cuando la tienda emite, debe volver a enviar los datos en commenListComponent para reflejar la tienda. Si usa React, aquí es donde usa setState.
var commentStore = _.extend({}, EventEmitter.prototype, {
updateComents: function() {
// Update comments and emit
this.emit(''change'');
},
removeComments: function() {
// Remove comments and emit
this.emit(''change'');
},
getState: function() {
return {
comments: this.comments,
someOtherDomainData: this.meta,
}
}
});
//commentListComponent.js
var commentListComponent = React.createClass({
componentDidMount : function() {
commentStore.on(''change'', this._commentChanged);
},
componentWillUnmount : function() {
commentStore.off(''change'', this._commentChanged);
},
_commentChanged : function() {
this.setState({ comments : commentStore.getState().comments });
},
render : function() {
var comments = // Build a list of comments.
return <div>{comments}</div>
}
})
Esto hace que el flujo de datos sea mucho más simple y evita errores difíciles de detectar.
Casi todos los tutoriales que encontré sobre el flujo emiten solo un evento por tienda (emitChange). Realmente no sé, que sea intencional, o simplemente la consecuencia de la simplicidad de los tutoriales.
Intento implementar una tienda, que corresponde a la arquitectura CRUD, y me pregunto si sería una buena decisión de diseño emitir diferentes eventos para cada método CRUD.
La parte relevante de una de mis tiendas se ve así:
var UserStore = _.extend({}, EventEmitter.prototype, {
emitChange: function() {
this.emit(''change'');
},
emitUserAdded: function() {
this.emit(''userAdded'');
},
emitUserUpdated: function() {
this.emit(''userUpdated'');
},
emitUserDeleted: function() {
this.emit(''userDeleted'');
},
// addListener, removeListener in the same manner
});
Si mi enfoque es incorrecto, ¿cómo le diría a mis componentes el tipo de evento que sucedió (por ejemplo, eliminar o actualizar)?
Mi caso de uso me obliga a usar eventos distintos. Tengo un componente de mapa que muestra muchos objetos complejos y sería muy costoso actualizar cada uno.
EventEmitter2 implementa EventEmitter2 múltiples EventEmitter2 y comodines. Me permite escuchar eventos de "cambio", o más específicamente eventos de subnivel "change.add" "change.remove" ...
this.emit("change.add");
puede estar escuchando por
myStore.on(''change.*'', callback);
myStore.on(''change.add'', callback);
De esta manera, muchos de mis componentes pueden simplemente escuchar el evento "change. *". Y los componentes más complejos que necesitan optimización pueden escuchar eventos específicos.
Lo mejor de ambos mundos
PD: no te olvides de habilitar comodines. Ver documentacion