据我所知,Redux是关于将UI的所有状态保存在一个商店中(以便能够轻松地再现某些状态并且没有副作用)。您可以通过触发减速器的触发操作来操纵状态。
我目前正在编写一个类似博客的小应用程序,您只需创建和编辑帖子即可。我有一个用于创建帖子的对话框,大致render
组件的App
方法返回如下内容:
<div>
<AppBar ... />
<PostFormDialog
addPost={actions.addPost}
ref="postFormDialog" />
<PostList
posts={posts}
actions={actions} />
</div>
我的问题是:对话框的状态(打开还是关闭)是否应该是App组件的状态对象的一部分?因此,应该通过操作触发打开和关闭对话框,而不是执行以下操作:
onTriggerCreatePostDialog(e) {
this.refs.postFormDialog.show();
}
其中onTriggerCreatePostDialog
是通过“创建”按钮左右的点击监听器触发的。
通过动作来做这件事似乎有点奇怪,因为它引入了一种“间接”。
但是,假设我想重用编辑操作的对话框,我必须能够从组件结构中更深层的元素打开对话框,例如从Post
组件开始,这是一个孩子PostList
组件。我能做的是通过onTriggerCreatePostDialog
属性将props
函数传递给层次结构,但这对我来说似乎很麻烦......
所以最后也是关于不直接父子关系的组件之间的通信。还有其他选择吗?我应该以某种方式利用全球事件总线吗?我目前不太确定。
答案 0 :(得分:7)
在我看来,你走的是正确的道路。一开始文档可能有点棘手,但我可以告诉你我和我的团队是如何使用这个实现的。
解决你的第一个问题;如果状态特定于组件,那么我们将该状态保持在组件中。这方面的一个例子是一个在本地记录记录的小组 - 没有其他任何东西需要知道这种行为。所以在这种情况下,当页面改变时我们不会触发redux动作,这将使用refs在组件结构内部处理。
我们的redux状态主要包括通过xhr请求或共享状态收集的数据。共享状态的示例是管理使用该范围来显示数据的多个组件之间的时间范围。在这种情况下,我们将触发redux动作;使用更改的任何内容更新日期状态(同时还通过xhr更新一些其他状态项),然后最终返回到组件并重新呈现。
话虽如此,通过refs触发动作是完全可以接受的,它只是具体的用例是什么。
解决你的第二个问题; redux建议使用Smart & Dumb组件概念。所以你是对的,你会在树下传递一个函数,以便使用愚蠢的组件。
我们在connect设置中使用mapDispatchToProps。所以基本上你传递一个函数,它返回一个函数对象&#34; dispatchers&#34;。您可以直接在智能组件this.props
中访问这些功能。
mapDispatchToProps的示例
function mapDispatchToProps(dispatch) {
return {
myAction: () => dispatch(actions.myAction()),
};
}
所以99%的时间都有效,但我遇到了一些我们使用全球事件总线的角落情况,所以不要害怕在尝试坚持智能的同时利用两者/尽可能使用哑元组件方法。
作为旁注,我建议使用reselect将您的redux状态映射到智能组件。您还可以找到其他很棒的redux资源here(我们列出了几个我们使用过的东西)。
答案 1 :(得分:2)
对话框的状态应位于由操作触发的redux存储中。应该通过检查redux商店中的状态来确定是否应该呈现。
App.render()
应该是这样的:
render() {
const { showDialog } = this.props;
return (
<div>
<AppBar ... />
{ showDialog ? <PostFormDialog ... /> : false }
<PostList ... />
</div>
);
}
其中mapStateToProps
类似于state => {{ showDialog: state.showDialog }}
在提供动作创建者方面,将它传递给道具树可能是正确的方法,除非你有一个好的位置,在那里有另一个智能组件是有意义的。