我发现todo flux app的示例有点缺乏,所以我试图通过开发一个学习和实验的应用程序来解决问题。
该应用程序是一个拖放水果篮组织者。我有几个篮子,可以在它们之间拖着各种水果。您可以通过单击突出显示一块水果,最后拖动的项目将保持突出显示。
基于此,我有3家商店:
当用户操作发生时,如果点击了水果,则AppStateStore会调度和处理FruitAction;如果水果已被移动到另一个篮子,则由AppStateStore处理。
主AppView组件侦听来自FruitStore和AppStateStore的更改事件并重新呈现。
我的问题是:
答案 0 :(得分:13)
FruitClicked
和FruitDragged
都可以是行动,商店会关注他们关心的行为。AppView
应该收听从中获取数据的所有商店。如果你在同一个标记中多次调用setState
,React会智能地合并它们,因此你实际上不会多次渲染。React网站上的文章确实讨论了在Creating Semantic Actions下发送自己的行为。在代码块中,页面上有几个滚动长度,您可以看到代码:
_onDestroyClick: function() {
TodoActions.destroy(this.props.todo.id);
}
本文还讨论了哪些组件应该在Listening to Changes with a Controller-View中监听商店:
我们需要在组件层次结构顶部附近的React组件来监听商店中的更改。在一个更大的应用程序中,我们将拥有更多这些监听组件,可能对于页面的每个部分都有一个。在Facebook的广告制作工具中,我们有许多类似控制器的视图,每个视图都管理UI的特定部分。在Lookback视频编辑器中,我们只有两个:一个用于动画预览,一个用于图像选择界面。
和
有时我们可能需要在层次结构中更深层地添加其他控制器视图以保持组件简单。这可以帮助我们更好地封装与特定数据域相关的层次结构的一部分。但请注意,层次结构中更深层次的控制器视图可能会通过为数据流引入新的,可能相互冲突的入口点来违反单一数据流。在决定是否添加深度控制器视图时,将更简单组件的增益与流入层次结构中的不同点的多个数据更新的复杂性进行平衡。这些多个数据更新可能会导致奇怪的效果,React的渲染方法会被来自不同控制器视图的更新重复调用,这可能会增加调试的难度。
答案 1 :(得分:5)
如果不理解应用程序,很难说这种方法是否合适。
然而,在我看来,点击水果应该由FruitStore处理。也就是说,一种水果已经获得了活跃的状态,已经变得可以拖延。如果这会以某种方式影响整个应用程序,那么这可能会导致AppStateStore发生变化。同样地,将水果从一个篮子移动到另一个篮子似乎是BasketStore的领域。
我想像FruitStore包含这样的私有数据结构:
var _fruit = {
1234: {
id: '1234',
type: 'apple',
active: false
},
2345: {
id: '2345',
type: 'orange',
active: false
},
3456: {
id: '3456',
type: 'apple',
active: false
}
};
我认为BasketStore有一个私有数据结构,如下所示:
var _baskets = {
4321: {
id: '4321',
name: 'Josephine\'s Basket',
fruitIDs: [
1234,
2345
]
},
5432: {
id: '5432',
name: 'Harold\'s Basket',
fruitIDs: [
3456
]
}
};
因此,水果"活跃" state由FruitStore管理,篮子的内容由BasketStore管理。
因此,如果适用于您的应用程序,AppView可以收听这两个商店。如上所述,重复调用render()方法的成本非常低。这并不会触及每次通话中的DOM - 这是React最大的优势之一。反过来,智能会智能地批量调用,只更新"脏" DOM的一部分,如果存在的话。
但也许您可能希望将篮子变成控制器视图。如果您确实选择将水果作为控制器视图,请务必清除componentWillUnmount()中的监听器,因为从篮子到篮子的水果移动可能需要销毁它们并重新创建。我认为在篮下听力更有意义,但同样,我也不太了解你的应用。
回答你的上一个问题:
是否有更完整的Flux架构示例或类似内容?
Facebook的工程师正在开发一个更复杂的应用程序示例,现在将展示waitFor()和服务器端持久存储的使用。我们希望尽快发布。