Ich schreibe meine App neu, um Flux zu verwenden, und habe ein Problem beim Abrufen von Daten aus Stores. Ich habe viele Komponenten und sie nisten viel. Einige von ihnen sind groß ( Article
), andere klein und einfach ( UserAvatar
, UserLink
).
Ich habe Probleme damit, wo in der Komponentenhierarchie ich Daten aus Stores lesen sollte.
Ich habe zwei extreme Ansätze ausprobiert, von denen mir keiner gefallen hat:
Alle Entitätskomponenten lesen ihre eigenen Daten
Jede Komponente, die einige Daten aus dem Store benötigt, empfängt nur die Entitäts-ID und ruft die Entität selbst ab.
Zum Beispiel Article
ist vergangen articleId
, UserAvatar
und UserLink
weitergegeben werden userId
.
Dieser Ansatz hat mehrere wesentliche Nachteile (siehe Codebeispiel).
var Article = React.createClass({
mixins: [createStoreMixin(ArticleStore)],
propTypes: {
articleId: PropTypes.number.isRequired
},
getStateFromStores() {
return {
article: ArticleStore.get(this.props.articleId);
}
},
render() {
var article = this.state.article,
userId = article.userId;
return (
<div>
<UserLink userId={userId}>
<UserAvatar userId={userId} />
</UserLink>
<h1>{article.title}</h1>
<p>{article.text}</p>
<p>Read more by <UserLink userId={userId} />.</p>
</div>
)
}
});
var UserAvatar = React.createClass({
mixins: [createStoreMixin(UserStore)],
propTypes: {
userId: PropTypes.number.isRequired
},
getStateFromStores() {
return {
user: UserStore.get(this.props.userId);
}
},
render() {
var user = this.state.user;
return (
<img src={user.thumbnailUrl} />
)
}
});
var UserLink = React.createClass({
mixins: [createStoreMixin(UserStore)],
propTypes: {
userId: PropTypes.number.isRequired
},
getStateFromStores() {
return {
user: UserStore.get(this.props.userId);
}
},
render() {
var user = this.state.user;
return (
<Link to='user' params={{ userId: this.props.userId }}>
{this.props.children || user.name}
</Link>
)
}
});
Nachteile dieses Ansatzes:
- Es ist frustrierend, dass 100s-Komponenten möglicherweise Stores abonnieren.
- Es ist schwierig zu verfolgen, wie Daten in welcher Reihenfolge aktualisiert werden, da jede Komponente ihre Daten unabhängig abruft.
- Auch wenn sich möglicherweise bereits eine Entität im Status befindet, müssen Sie ihre ID an untergeordnete Elemente weitergeben, die sie erneut abrufen (oder die Konsistenz beeinträchtigen).
Alle Daten werden einmal auf der obersten Ebene gelesen und an die Komponenten weitergegeben
Als ich es satt hatte, Fehler aufzuspüren, habe ich versucht, alle Daten, die abgerufen wurden, auf die oberste Ebene zu bringen. Dies erwies sich jedoch als unmöglich, da ich für einige Entitäten mehrere Verschachtelungsebenen habe.
Beispielsweise:
- A
Category
enthältUserAvatar
s von Personen, die zu dieser Kategorie beitragen; - Ein
Article
kann mehrereCategory
s haben.
Wenn ich also alle Daten aus Stores auf der Ebene von abrufen Article
möchte, muss ich:
- Artikel abrufen von
ArticleStore
; - Rufen Sie alle Artikelkategorien von ab
CategoryStore
. - Rufen Sie die Mitwirkenden jeder Kategorie separat ab
UserStore
. - Übergeben Sie all diese Daten irgendwie an Komponenten.
Noch frustrierender ist, dass ich, wenn ich eine tief verschachtelte Entität benötige, jeder Verschachtelungsebene Code hinzufügen muss, um sie zusätzlich weiterzugeben.
Zusammenfassen
Beide Ansätze scheinen fehlerhaft zu sein. Wie löse ich dieses Problem am elegantesten?
Meine Ziele:
Geschäfte sollten nicht wahnsinnig viele Abonnenten haben. Es ist dumm
UserLink
,UserStore
wenn jeder zuhört, wenn übergeordnete Komponenten dies bereits tun.Wenn die übergeordnete Komponente ein Objekt aus dem Speicher abgerufen hat (z. B.
user
), möchte ich nicht, dass verschachtelte Komponenten es erneut abrufen müssen. Ich sollte es über Requisiten weitergeben können.Ich sollte nicht alle Entitäten (einschließlich Beziehungen) auf der obersten Ebene abrufen müssen, da dies das Hinzufügen oder Entfernen von Beziehungen erschweren würde. Ich möchte nicht jedes Mal neue Requisiten auf allen Verschachtelungsebenen einführen, wenn eine verschachtelte Entität eine neue Beziehung erhält (z. B. Kategorie erhält eine
curator
).