React:在ComponentWillMount中添加更新Stores的Actions是个坏主意吗?

时间:2015-11-17 23:26:01

标签: reactjs react-router flux reactjs-flux

工具:Reactjs 0.14.0,React-Router 1.0.0,Vanilla Flux

所以我将Action推送到componentWillMount中的商店,它现在抛出错误:

"未捕获(承诺)错误:不变违规:Dispatch.dispatch(...):无法在发送过程中发送"

我的所有调度都应该在这次电话会议之前完成,但是 终于我意识到我的最终emitChange()没有回来,直到显然所有重新渲染emitChange()导致。

示例代码流程1-4:

1)我在InitStore中更改InitComplete现在为真的状态

InitStore.js

case ActionTypes.INIT_COMPLETE:
    _initComplete();
    InitilizationStore.emitChange();
    // Not getting past here till all re-rendering was done
    break;

2)现在将触发更改渲染

app.js

if(this.state.initComplete) {
    return (
        <Main />
    );
}else{ 
   return (<div className="main-container">Loading...</div>);
}

3)在Main的子组件中,将调用componentWillMount

来保存路由的参数

Threadlist.js

componentWillMount: function(){
    var { threadID } = this.props.params
    ThreadActionCreators.setCurrentThread(threadID);//Invariant!!!No!!
},

4)但看起来InitStore还没有从emitChange()回来!

问题:   那么我通常不应该在componentWillMount中更新商店吗?

1 个答案:

答案 0 :(得分:1)

当操作同步触发另一个操作时,会发生“无法在调度中间发送”。操作旨在作为数据更改的通知,所有结果逻辑由商店处理,而不需要触发后续的进一步操作,因此触发另一个操作的操作可能表明您做错了。

但是,在某些情况下,例如您的情况,想要触发进一步操作以响应新组件的创建或更新是合理的。在这些情况下,您可以通过使第二个操作异步来避免调度错误。最简单的方法是将第二个动作放在setTimeout中:

componentWillMount: function(){
    var { threadID } = this.props.params
    window.setTimeout(
        function () {ThreadActionCreators.setCurrentThread(threadID);},
        0
    );
},

或者,如果您愿意,可以在超时中将调度调用放在setCurrentThread()中,否则应该有效。