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

Javascript 在React Flux上,我应该在哪里填充我的商店的初始状态?,javascript,reactjs,reactjs-flux,flux,Javascript,Reactjs,Reactjs Flux,Flux,我在学习Flux,我想我理解了工作流程: View -> Action -> Dispatcher -> Store -> View 然而,我不太明白我应该在哪里填充我的商店的初始状态 例如,假设我正在编辑一个联系人。所以我假设我有一个联系人存储。这就是我在访问URL/contacts/edit/23时想象的情况: 不知何故,我的ContactsStore中填充了我正在编辑的联系人,在本例中是联系人23。数据将来自服务器 EditContact视图将收到来自Contac

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

View -> Action -> Dispatcher -> Store -> View
然而,我不太明白我应该在哪里填充我的商店的初始状态

例如,假设我正在编辑一个联系人。所以我假设我有一个
联系人存储
。这就是我在访问URL
/contacts/edit/23
时想象的情况:

  • 不知何故,我的
    ContactsStore
    中填充了我正在编辑的联系人,在本例中是联系人23。数据将来自服务器
  • EditContact
    视图将收到来自
    ContactsStore
    的通知,因此它将呈现初始状态
  • 当我保存联系人时,视图将触发
    SaveContact
    操作,流程将继续
  • 我不清楚第(1)步。预计将使用初始状态填充的
    联系人存储在哪里?我在哪里呼叫服务器?它在商店里吗


    谢谢。

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

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

    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() {
            ...
        }
    });
    

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

    在您的高级组件(容器):componentWillMount处理程序中,您可以启动一个执行api请求的操作,一旦成功,此状态将保存到存储中,存储收到联系人后,它将启动EditContact组件容器已订阅的事件->并将其传递给EditContact组件

    州应位于您的商店:)


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

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

    例如,使用its,您可以指定每个路由(例如,
    /contacts/23
    )应触发一个操作

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