在React Flux上,我应该填充我的商店的初始状态?

时间:2015-07-23 13:47:21

标签: javascript reactjs reactjs-flux flux

我正在学习Flux,我想我理解了工作流程:

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

然而,我并不完全明白我应该在哪里填充我的商店的初始状态。

例如,让我们说我正在编辑联系人。所以我假设我有ContactsStore。这是我在访问网址/contacts/edit/23时会想到的:

  1. 我的ContactsStore以某种方式填充了我正在编辑的联系人,在这种情况下,请联系23.数据将来自服务器。
  2. EditContact视图会收到来自ContactsStore的通知,因此会将自身呈现为初始状态。
  3. 当我保存联系人时,视图会触发SaveContact操作,流程将会继续。
  4. 步骤(1)对我来说并不清楚。 ContactsStore预计在哪里填充初始状态?我在哪里打电话给服务器?它在商店吗?

    感谢。

4 个答案:

答案 0 :(得分:5)

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

答案 1 :(得分:3)

我和其他许多人这样做的方式是我从视图中触发一个动作来加载联系人。我们称之为LOAD_CONTACT。这将是一个异步操作。有些人直接将API调用放在商店中,但我认为在动作创建者中进行异步工作更常见。因此,我们假设您有一个动作创建者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() {
        ...
    }
});

答案 2 :(得分:1)

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

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

州应该住在你的商店:)

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

答案 3 :(得分:0)

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

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

例如,使用fluxible-routerrouting configuration允许您指定每条路线(例如/contacts/23)应触发操作。

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