在 React Flux 上,我应该在哪里填充我的 Store 的初始状态?

Posted

技术标签:

【中文标题】在 React Flux 上,我应该在哪里填充我的 Store 的初始状态?【英文标题】:On React Flux, where I am supposed to populate the initial state of my Stores? 【发布时间】:2015-10-13 20:57:43 【问题描述】:

我正在研究 Flux,我想我理解了工作流程:

View -> Action -> Dispatcher -> Store -> View

但是,我不太明白应该在哪里填充我的 Store 的初始状态。

例如,假设我正在编辑联系人。所以我假设我有一个ContactsStore。这就是我想象当我访问 URL /contacts/edit/23 时会发生的事情:

    不知何故,我的ContactsStore 填充了我正在编辑的联系人,在本例中为联系人 23。数据将来自服务器。 EditContact 视图会收到来自ContactsStore 的通知,因此它会将自身呈现为初始状态。 当我保存联系人时,视图将触发 SaveContact 操作,流程将继续。

步骤 (1) 我不清楚。 ContactsStore 应该在哪里填充初始状态?我在哪里调用服务器?商店上有吗?

谢谢。

【问题讨论】:

【参考方案1】:

当您构建应用的初始状态时,您应该触发一个操作来获取“联系人 23”的数据。该操作进行异步调用,从而产生一个事件,该事件填充存储,组件使用该存储获取其状态。

但是,您是否要将触发操作的逻辑放入该组件中?不必要。您是否使用任何路由库?如果是这样,它们可能是触发动作的最佳位置。

例如,使用fluxible-router,它的routing configuration 允许您指定每个路由(例如/contacts/23)应该触发一个动作。

这让您可以将如何显示数据与如何检索数据分离。您可以使用相同的组件并让它在一种情况下从 AJAX 获取数据,在另一种情况下从本地存储获取数据,等等。您还可以优化数据的获取,例如通过将多个调用捆绑在一起,无需更改任何组件。

【讨论】:

【参考方案2】:

我同意 Florian Gl 的回答 虽然我建议阅读下面关于高阶组件的文章,但您应该将逻辑排除在组件之外,并使用将数据作为道具传递的高阶组件,尽可能避免使用状态,它只会增加额外的复杂性

在您的更高级别组件(容器):componentWillMount 处理程序中,您可以触发一个执行 api 请求的操作,成功时此状态将保存到商店,并且一旦商店收到联系,它就会触发一个事件,在该事件上EditContact 组件 Container 已订阅 -> 传递给 editContact 组件

状态应该存在于您的商店中:)

https://medium.com/@dan_abramov/mixins-are-dead-long-live-higher-order-components-94a0d2f9e750

【讨论】:

【参考方案3】:

我以及我认为许多其他人的方式是我从视图中触发一个动作来加载联系人。我们称之为LOAD_CONTACT。这将是一个异步操作。有些人直接将 API 调用放在 store 中,但我认为在 action creators 中做异步工作更常见。因此,假设您有一个动作创建者loadContactAction()。然后首先调度 LOAD_CONTACT 操作(以防某些商店可能对此感兴趣,以显示“正在加载”消息或其他内容),然后从 API 获取。在 ajax 请求的回调中,您调用另一个动作创建者,例如loadContactSuccessAction()(或“失败”,当然)。然后您的ContactsStore 商店注册并响应LOAD_CONTACT_SUCCESSFUL

var loadContactAction = function(...) 
    // maybe do some work
    dispatch(...); // dispatch your LOAD_CONTACT action

    makeRequest(...).then(function(contact) 
        loadContactSuccessAction(contact); // create "success" action
    , function(err) 
        loadContactFailedAction(err); // probably handle this somewhere
    );


var ContactsStore = 
    init(...) 
        // register in dispatcher here
    ,
    onLoadContactSuccess(contact) 
        this.contacts[contact.id] = contact; // or store your contact some other way
        this.emitChange(); // trigger a store update change event with whatever event dispatcher you use
    


var EditContact = React.createClass(
    componentDidMount: function() 
        ContactsStore.listen(this.onStoreChange);
        loadContactAction(); // pass in ID or however you want to load it
    ,
    onStoreChange: function() 
        // fetch your contact here
    ,
    render: function() 
        ...
    
);

【讨论】:

【参考方案4】:

您需要访问EditContact 组件中的操作和存储。在 componentDidMount 处理程序中,您可以触发执行 api 请求的操作。成功后,它将联系人传递给dispatcher/store。一旦商店收到contact,它就会触发EditContact 组件已订阅的事件。在相应的处理程序中,组件使用新联系人设置新状态。我确信还有其他方法可以做到这一点,但我就是这样做的。

【讨论】:

以上是关于在 React Flux 上,我应该在哪里填充我的 Store 的初始状态?的主要内容,如果未能解决你的问题,请参考以下文章

模型助手在 React/Flux 中属于哪里?

在 Flux/React.js 中,在哪里初始化 jQuery 插件?

react/flux- 子组件用户事件 - 一切都应该通过调度程序路由吗

如果我开始使用 React/flux,我应该从头开始重新创建我的所有页面(html 和 css)吗?

React / Flux:我应该让商店听取其他商店的更改吗?

画布库如何适应 Flux 模式和 React?