Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dispatch doesn't reach enhancers (sagas, loggers) #131

Closed
panta82 opened this issue Aug 16, 2016 · 6 comments
Closed

Dispatch doesn't reach enhancers (sagas, loggers) #131

panta82 opened this issue Aug 16, 2016 · 6 comments

Comments

@panta82
Copy link

panta82 commented Aug 16, 2016

I'm a noob with react native, so excuse me if I'm missing something obvious.

I created a new ignite app. I modified App/Sagas/index.js with the following content:

function * test() {
  while (true) {
    yield take('DEV');
    console.log('dev');
  }
}

// start the daemons
export default function * root () {
  yield fork(watchStartup)
  yield fork(watchLoginAttempt)
  yield fork(getCityWeather(api).watcher)

  yield fork(test);
}

(I added the test function).

I modified the Startup saga like this:

export function * watchStartup () {
  yield take(Types.STARTUP);
  yield put({type: 'DEV'}); // <--- added by me
  const temp = yield select((state) => state.weather.temperature)
  // only fetch new temps when we don't have one yet
  if (!R.is(Number, temp)) {
    yield put(Actions.requestTemperature('San Francisco'))
  }
}

When I launch the app, I see the DEV saga logged in console, and "dev" being written in the chrome console. I can also see the DEV action logged in reactotron.

Then I try to trigger this action from the reactotron interface ({type: 'DEV'}).

image

Nothing happens. My saga isn't activated, nothing is logged in the console nor reactotron.

I think the problem is between the way your createSubscriptionListener and redux's applyMiddleware handle the store. Here are the relevant code snippets, in the order of execution.

reactotron/dist/client.js
    return function (reducer, initialState, enhancer) {
      // create this store
      var store = createStore(reducer, initialState, enhancer);

      // (snip)

      // attach the subscription to the store
      client.addReduxStore(store);  // <-- store version 1 sent to the addReduxStore

      // return the store but with our new dispatcher
      return R.merge(store, { dispatch: dispatch }); // <-- store version 2 returned
    };

//.....

client.addReduxStore = function (store) {
  store.subscribe(client.createSubscriptionListener(store)); // <-- store version 1 cached in this closure
  //...
redux/lib/applyMiddleware.js
      var store = createStore(reducer, initialState, enhancer); // <-- store version 2 appears here
      var _dispatch = store.dispatch;
      var chain = [];

      var middlewareAPI = {
        getState: store.getState,
        dispatch: function dispatch(action) {
          return _dispatch(action);
        }
      };
      chain = middlewares.map(function (middleware) {
        return middleware(middlewareAPI);
      });
      _dispatch = _compose2["default"].apply(undefined, chain)(store.dispatch);  // <-- all the middleware / enhancers added here

      return _extends({}, store, { // <-- store version 3 returned to the rest of the app
        dispatch: _dispatch
      });

As you can see, reactotron's listener ends up with a bizzaro alternate universe version of the store, without any of the enhancers applied (including sagas, logging, etc.).

@zalmoxisus
Copy link

Similarly to Redux DevTools extension and Remote Redux DevTools, there should be an updateStore method.

When reduxjs/redux#1702 gets merged, this workaround wouldn't be necessary.

@skellock
Copy link
Contributor

I actually experienced in the rebuild too. I thought I was loosing my mind.

Thanks for the info @zalmoxisus , i appreciate the heads up ❤️

@panta82
Copy link
Author

panta82 commented Aug 18, 2016

For what it's worth, to fix my problem, I ended up removing this line

      // attach the subscription to the store
      client.addReduxStore(store);

from the storeEnhancer, and calling it after I have the completed store object.

Not sure if this is viable solution for the library itself, though.

@skellock
Copy link
Contributor

Thank you very much for following up.

@skellock
Copy link
Contributor

Hey, so following up here to probably say something y'all already know.

Seems like the enhancer order matters. Putting the Reactotron enhancer first seems to solve the issue. I'm not sure it was always like this?

I probably broke something but this used to work. =) I've documented this now in the new version.

In any case, just wanted to say thank you to both of you again.

@skellock
Copy link
Contributor

skellock commented Nov 3, 2016

Fix incoming in #230 tomorrow.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants