我正在重写我的应用程序以使用Flux,我在从store 检索数据时遇到了问题.我有很多组件,它们嵌套了很多.其中一些是大的(Article
),一些是小而简单的(UserAvatar
UserLink
).
I've been struggling with where in component hierarchy I should read data from Stores.
I tried two extreme approaches, neither of which I quite liked:
所有实体组件都读取自己的数据
Each component that needs some data from Store receives just entity ID and retrieves entity on its own.
For example, Article
is passed articleId
, UserAvatar
and UserLink
are passed 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>
)
}
});
这种方法的缺点:
- 有100个组件可能订阅store ,这令人沮丧;
- 它是hard to keep track of how data is updated and in what order,因 for each 组件独立检索其数据;
- 即使您可能有一个处于状态的实体,您也必须将其ID传递给子级,子级将再次检索它(否则会 destruct 一致性).
所有数据在顶层读取一次,并传递给组件
当我厌倦了追踪bug时,我试着将所有数据检索放在顶层.然而,事实证明这是不可能的,因为对于某些实体,我有几个层次的嵌套.
例如:
-
Category
人中有UserAvatar
人对该类别做出了贡献; -
Article
可能有几个Category
.
因此,如果我想从Article
级的存储中检索所有数据,我需要:
- 从
ArticleStore
中检索文章; - 从
CategoryStore
中检索所有文章的类别; - 分别从
UserStore
个类别中检索每个类别的贡献者; - 以某种方式将所有数据传递给组件.
更令人沮丧的是,每当我需要一个深度嵌套的实体时,我都需要在每一层嵌套中添加代码来进一步传递它.
总结
这两种方法似乎都有缺陷.我怎样才能最优雅地解决这个问题?
我的目标:
-
store 不应该有疯狂的订户数量.如果父组件已经这样做了,那么每
UserLink
个都听UserStore
是愚蠢的. -
如果父组件已从存储中检索到某个对象(例如
user
),我不希望任何嵌套组件必须再次检索它.我应该可以通过props 传递. -
我不必在顶层获取所有实体(包括关系),因为这会使添加或删除关系变得复杂.我不想每次嵌套实体获得新关系时(例如,类别获得
curator
)在所有嵌套级别引入新的props .