Search code examples
reactjsflux

Make stores listen to change in another store


I have a Flux app with 2 stores: ACCOUNT-STORE and CLIENT-STORE.

Currently the app lets the user filter for a specific country and the whole filter logic has been implemented into each store (since both account data and client data have to be filtered by country). So both store: 1- listen to a SELECT_COUNTRY action triggered by a component 2- create a filter function that will keep only the selected country 3- apply that function to their data

Since the number of filters will grow, I was wondering if it would be possible to move steps 1 and 2 into a third store that would just manage the filters: FILTER-STORE.

Now FILTER-STORE listen to SELECT_COUNTRY and create the filter function, but I cannot find the best practices to make ACCOUNT-STORE and CLIENT-STORE listen and react to change in FILTER-STORE.

In the AppDispatcher.register of FILTER-STORE, I tried to call another action after creating the filter function:

switch (action.actionType) {
    case AppConstants.SELECT_ACCOUNT:
        updateAccountFilter(action.data);
        AppActions.stfil_selectAccount(
            FilterStore.getAccountFilter()
        );
        break;

My plan was to make ACCOUNT-STORE and CLIENT-STORE listen to this action and use its payload. But I fall on the error message:

Invariant Violation: Dispatch.dispatch(...): Cannot dispatch in the middle of a dispatch.

So maybe there is another way? Is it possible to make ACCOUNT-STORE and CLIENT-STORE listen to FILTER-STORE just like my components listen to stores?

Thanks


Solution

  • The thing you are trying to do goes against Flux unidirectional data flow architecture, explained here. Stores shouldn't emit changes for themselves to listen, the should only listen to actions from components and emit changes to components as well.

    If you want to DRY your filter logic, you should create a corresponding FilterActionCreator that will handle dispatching SELECT_ACCOUNT and other actions. You can read more about it in this extensive answer.

    This will keep your logic DRY and your flow safe.