gcazaciuc / redux-fractal

Sane local component state & actions using Redux
MIT License
178 stars 13 forks source link

Middleware issues - async actions do not reach the global store #45

Open tuttleb opened 7 years ago

tuttleb commented 7 years ago

I believe this issue is caused by the middleware being applied before redux-fractal sets up the local dispatch function on the local store. If you look at https://github.com/reactjs/redux/blob/master/src/applyMiddleware.js#L22 you can see that the middleware grabs store.dispatch only once on initialization. Following that trail to https://github.com/reactjs/redux/blob/master/src/createStore.js#L50 you will see that the middleware is applied immediately as part of the store creation process.

For example:

export default function configureStore() {
    let store = createStore(
        rootReducer,
        defaultState,
        applyMiddleware(
            thunkMiddleware
        )
    );
    return store;
}

thunk will initialize with the store's original dispatch function, not the wrapped local dispatch function. This means that actions dispatched by middleware only apply to the local store, and will never reach the global store.

JIM-CHEN commented 7 years ago

Hi tuttleb,

My issue is different with you, I can get async action in global via redux-thunk but not in local. Can you get async action in local via redux-thunk?

Thanks!

mgutz commented 7 years ago

@JIM-CHEN I have same issue. Nothing locally. Most of our actions are async so this package is not very useful at the moment.

amosyuen commented 7 years ago

I ran into the same problem as tuttleb, locally dispatched actions in middleware don't reach global middleware. Essentially the library needs a way to replace the dispatcher before passing it to the middleware.

Not sure if there's a clean way to fix this without breaking the API. My guess is probably the best thing would be to have a new breaking version where the user specified createStore param return the params for creating a store (reducer, initialState, enhancer) rather than explicitly creating it. That way the lib can always replace the dispatcher and create the store itself.

I made a hacky fix that exposes a createLocalStore() method that replaces the dispatcher, which I use in place of the normal redux createStore(). https://github.com/amosyuen/redux-fractal/commit/f408fd4360eaad74c4a802f8ffeb6b0f5b8aa968