Fluxを使用するようにアプリを書き換えていますが、ストアからのデータの取得に問題があります。私はたくさんのコンポーネントを持っていて、それらはたくさん入れ子になっています。それらのいくつかは大きく(Article
)、いくつかは小さくてシンプルです(UserAvatar
、UserLink
)。
私はストアからデータを読み取る必要があるコンポーネント階層のどこに苦労してきました。
私は2つの極端なアプローチを試しましたが、どちらもかなり気に入りました。
すべてのエンティティコンポーネントが独自のデータを読み取る
Storeからのデータを必要とする各コンポーネントは、エンティティIDのみを受け取り、エンティティを独自に取得します。
たとえば、Article
渡されarticleId
、UserAvatar
そしてUserLink
渡されますuserId
。
このアプローチには、いくつかの重大な欠点があります(コードサンプルで説明)。
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>
)
}
});
このアプローチの欠点:
- Storesにサブスクライブする可能性のある100のコンポーネントがあるとイライラします。
- それはですどのようにデータが更新されており、中にどのような順序のトラックに保つのは難しい各コンポーネントは独立してそのデータを取得するために、
- エンティティがすでに存在している場合でも、そのIDを子に渡さなければなりません。子は再びエンティティを取得します(または整合性を壊します)。
すべてのデータはトップレベルで一度読み込まれ、コンポーネントに渡されます
バグの追跡にうんざりしているとき、私はすべてのデータの取得を最上位に配置しようとしました。ただし、一部のエンティティにはいくつかのレベルのネストがあるため、これは不可能であることが判明しました。
例えば:
- Aに
Category
はUserAvatar
、そのカテゴリに貢献するsの人々が含まれます。 - に
Article
は複数Category
のがある場合があります。
したがって、のレベルでStoreからすべてのデータを取得したい場合はArticle
、次のことを行う必要があります。
- から記事を取得し
ArticleStore
ます。 - からすべての記事のカテゴリを取得し
CategoryStore
ます。 - から各カテゴリの貢献者を個別に取得します
UserStore
。 - なんとかしてすべてのデータをコンポーネントに渡します。
さらにイライラすることに、深くネストされたエンティティが必要な場合は、ネストの各レベルにコードを追加して、さらに渡す必要があります。
まとめ
どちらのアプローチにも欠陥があるようです。この問題を最もエレガントに解決するにはどうすればよいですか?
私の目的:
店舗には、非常に多くの加入者がいるべきではありません。親コンポーネントが既にそれを行っている場合、それぞれ
UserLink
がリッスンするのは愚かですUserStore
。親コンポーネントがストアからオブジェクトを取得した場合(例
user
:)、ネストされたコンポーネントが再度フェッチする必要はありません。小道具を介して渡すことができるはずです。関係の追加や削除が複雑になるため、すべてのエンティティ(関係を含む)をトップレベルでフェッチする必要はありません。ネストされたエンティティが新しい関係を取得するたびに(たとえば、カテゴリがを取得するなど
curator
)、すべてのネストレベルで新しい小道具を導入したくありません。