tappleby / redux-batched-subscribe

store enhancer for https://github.com/reactjs/redux which allows batching subscribe notifications.
MIT License
504 stars 32 forks source link

Confused as to order of execution for notify() #23

Closed mlodato517 closed 6 years ago

mlodato517 commented 6 years ago

Hi, I'm not sure if my project is set up weird or anything, but I have a store that looks like

import { createStore } from 'redux';
import { Map } from 'immutable';
import rootReducer from './reducers';
import { batchedSubscribe } from 'redux-batched-subscribe';

let notifier = 0;
const notifyAndSetFlag = (notify) => {
  notifier = 0;
  console.log("Notifying");
  notify();
};
const debouncer = (notify) => {
  clearTimeout(notifier);
  notifier = setTimeout(notifyAndSetFlag.bind(null, notify), 200);
};

export default function configureStore(initialState) {
  return createStore(rootReducer, initialState || Map(), batchedSubscribe(notify => debouncer(notify)));
}

And a very simple application with one text field that, when I type into it, it dispatches an action to update some text on the screen. I've entered logging statements in mapStateToProps, render, the reducer, and in notifyAndSetFlag. When I type "asdf" quickly, I would normally expect to see

reducer
reducer
reducer
reducer
notify
mapstatetoprops
render
mapstatetoprops
render
mapstatetoprops
render
mapstatetoprops
render

But instead I see

reducer
mapstatetoprops
render
reducer
mapstatetoprops
render
reducer
mapstatetoprops
render
reducer
mapstatetoprops
render
notify

Is my store set up incorrectly or is this an issue with batched subscribe or is there some other problem? When I put in a breakpoint, it looks like

var listeners = currentListeners = nextListeners;
    for (var i = 0; i < listeners.length; i++) {
      var listener = listeners[i];
      listener();
    }

is still being called in redux dispatch(). Should that not happen?

mlodato517 commented 6 years ago

Never mind, it appears that when the listeners loop is called, the length is always 0, so that's good. It seems that listener() is only called in the debounced function call. But am I correct in thinking that mapStateToProps and render shouldn't be called until notify is called?

I should mention that I also have reselect installed. Not sure if that changes the timing of when mapStateToProps is called.

mlodato517 commented 6 years ago

Yes, this seems to be an issue of reselect. I switched to another branch that never had reselect installed and the notify scheme seemed to work. Sorry about that.