2015-06-27 9 views
17

Quasi tutte le esercitazioni che ho trovato sul flusso emettono solo un evento per negozio (emitChange). Non so davvero, che sia intenzionale, o solo la conseguenza della semplicità delle esercitazioni.È un buon design, quando un negozio React Flux emette più tipi di eventi?

Cerco di implementare un negozio, che corrisponde all'architettura CRUD, e mi chiedo se sarebbe una buona decisione progettuale emettere eventi diversi per ogni metodo CRUD.

La parte rilevante di uno dei miei negozi simile a questa:

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 
}); 

Se il mio approccio è sbagliato, come avrei dico ai miei componenti il ​​tipo di evento, quello accadesse (ad esempio: cancellazione o l'aggiornamento)

+0

Non ho familiarità con 'react' in particolare, ma le considerazioni principali in generale sono il bilanciamento della scrittura di un codice wireplare di tipo boilerplate per avere tipi di eventi discreti per ogni entità e ogni gestore di eventi di aggiornamento che attiva ogni volta un 'update' viene pubblicato invece di avere un evento di gestione eventi quando viene pubblicato' userUpdated'. Quanto potenza ha il tuo ambiente di runtime? – arootbeer

+0

'Quanto potenza ha il tuo ambiente runtime?' - Cosa significa questa domanda? – gsanta

+0

Penso che reagire non sia appropriato per un evento di aggiornamento, perché ogni negozio rappresenta un'entità indipendente. Quindi l'evento deve provenire, ad esempio da UserStore, quindi non è stato possibile generare un evento di aggiornamento generale. Tuttavia, potrei lanciare un semplice evento di cambiamento dal mio UserStore e fornire come parametro se si tratta di un aggiornamento o di un minimo altro. Non so se sarebbe l'approccio migliore. – gsanta

risposta

12

Il flusso come modello di progettazione si basa sull'idea che tutti i dati risiedano in "negozi". Ogni negozio contiene dati per un dato dominio di informazioni. Ad esempio: in Flux, tutti i commenti dovrebbero risiedere in un CommentStore.

Quando i dati vengono modificati in un negozio, è necessario emettere un evento e tutti i componenti che si sviluppano sopra questo "dominio delle informazioni", devono eseguire nuovamente il rerender e visualizzare i nuovi dati del dominio.

Ho scoperto che quando un negozio emette più tipi di eventi, è più probabile che i componenti non ascoltino quell'evento specifico, quindi non si riorganizzano quando i dati dei domini vengono modificati.

Questo interrompe l'intero schema di flusso e può facilmente creare bug difficili da trovare dove i componenti non sono sincronizzati con le informazioni del negozio.

Vorrei invece consigliare di progettare i componenti dalla "Legge di Demeter" - ogni componente dovrebbe solo sapere quanto necessario.

Quindi, anziché il componente che ascolta un evento che dice "commentList è stato aggiornato", è necessario creare un componente CommentList che ascolti un evento di un singolo negozio. Quindi, il componente ascolterà su commentStore.on ('cambia') - Di solito permetto a tutti i negozi di emettere un evento 'change'. Quando il negozio emette, è necessario rileggere i dati nel commenListComponent per riflettere lo store. Se si utilizza React, questo è dove si 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> 
    } 
}) 

Questo rende il flusso dei dati molto più semplice ed evita errori di difficile individuazione.

+1

Grazie per la risposta. Tuttavia non è chiaro per me, come è possibile differenziare i tipi di eventi in questa architettura. Ad esempio diciamo che l'utente elimina un commento. Come puoi dire al componente che la cancellazione ha avuto successo? – gsanta

+2

Non dovresti. Questo è il punto. Lascia che il negozio gestisca tutta la logica e lascia che il componente renda solo lo stato restituito dal negozio. un componente che esegue il rendering di tutti i commenti in un elenco non ha bisogno di sapere se un commento viene rimosso, ma deve solo rerenderlo con tutti i commenti. – Silfverstrom

+9

Ok, vedo che il componente CommentList non deve saperlo. Ma immagina un componente popup, che informa l'utente che l'eliminazione è avvenuta con successo (assegnagli un nome a CommentPopup). Quindi questo componente ha bisogno di qualche evento, che dice che è avvenuta una cancellazione, come lo risolveresti? – gsanta

0

Il mio caso d'uso mi obbliga a utilizzare eventi distinti. Ho un componente di mappa che mostra molti oggetti complessi e sarebbe molto costoso aggiornarli.

EventEmitter2 implementa eventi multilivello e caratteri jolly. Mi permette di ascoltare gli eventi "cambiamento", o più precisamente gli eventi sub-livello "change.add" "change.remove" ...

this.emit("change.add"); 

può essere in ascolto da

myStore.on('change.*', callback); 
myStore.on('change.add', callback); 

In questo in questo modo, molti dei miei componenti possono semplicemente ascoltare l'evento "change. *". E i componenti più complessi che necessitano di ottimizzazione possono ascoltare eventi specifici.

Il meglio dei due mondi

PS: non dimenticate di abilitare i caratteri jolly.Vedere la documentazione

Problemi correlati