Avoiding event chains with asynchronous data dependencies

不羁岁月 提交于 2019-12-03 05:36:28
fisherwebdev

Whenever you are retrieving the state of the application, you want to be retrieving that state directly from the Stores, with getter methods. Actions are objects that inform Stores. You could think of them as being like a request for a change in state. They should not return any data. They are not a mechanism by which you should be retrieving the application state, but rather merely changing it.

So in scenario 1, getCurrent(category.id) is something that should be defined on a Store.

In scenario 2, it sounds like you are running into an issue with the initialization of the Store's data. I usually handle this by (ideally) getting the data into the stores before rendering the root component. I do this in a bootstrapping module. Alternatively, if this absolutely needs to be async, you can create everything to work with a blank slate, and then re-render after the Stores respond to an INITIAL_LOAD action.

For scenario 1:

I would dispatch new the action from the view itself, so a new action -> dispatcher -> store -> view cycle will trigger.

I can imagine that your view needs to retrieve the category list and also it has to show, by default, the list of products of the first category.

So that view will react to changes con CategoryStore first. Once the category list is loaded, trigger the new Action to get the products of the first category.

Now, this is the tricky part. If you do that in the change listener of the view, you will get an invariant exception, so here you have to wait for the payload of the first action to be completely processed.

One way to solve this is to use timeout on the change listener of the view. Something similar to what is explained here: https://groups.google.com/forum/#!topic/reactjs/1xR9esXX1X4 but instead of dispatching the action from the store, you would do it from the view.

function getCategoryProducts(id) {
setTimeout(() => {
    if (!AppDispatcher.isDispatching()) {
        CategoryProductActions.get(id);
    } else {
        getCategoryProducts(id);
    }
}, 3);
}

I know, it is horrible, but at least you won't have stores chaining actions or domain logic leaking to action creators. With this approach, the actions are "requested" from the views that actually need them.

The other option, which I haven't tried honestly, is to listen for the DOM event once the component with the list of categories is populated. In that moment, you dispatch the new action which will trigger a new "Flux" chain. I actually think this one is neater, but as said, I haven't tried yet.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!