redux-batched-actions
redux-batched-actions copied to clipboard
batchActions causing a render after each action, rather than after the completion of all three
This is my call with batchActions
dispatch(batchActions([
this.props.actions.setTags({ tags : activeTags }),
this.props.actions.setNuggets({ nuggets : activeNuggets}),
this.props.actions.setSelectedDomain({ selectedDomainId : nextActiveDomain }),
]))
I've put a console.log
in each of my reducers. The app crashes before the second one prints out as, since the data is intimately connected, they are mismatched when only one part of the store refreshes. The odd thing is, is this worked as expected before some refactoring. I've tried both calling enableBatching
on my rootReducer
and without, and same result.
Any ideas?
Just to be very clear, my intention in using redux-batched-actions
is to update separate parts of my store but have only one notification emitted, resulting in one render after all state modifications are complete. Upon closer look to redux source code, dispatch
immediately calls all of the listeners once it obtains a new state from the reducer
. Nothing a higher order function, like batchActions
, could change. Have I misunderstood the purpose or use of this library?
@dgaitsgo From the sound of it, this library does exactly what you're hoping to achieve. Can you send more context of how you set up the store with your reducer? If you are using enableBatching
and batchActions
properly, it should be working for you.
Okay,
I've isolated the issue. The code above fails if it is in the callback of a Promise.
api.insert(persistUi).then(res => {
/*code from above*/
})
but, why?
I'm sorry I can't make a more generic example to reproduce the error, but this is as simple as I can get.
A promise to wait for :
resolveAfterSecond = x => new Promise (res => setTimeout(() => res(x), 1000) )
test = async (nextActiveDomain) => {
const { allNuggets } = this.props.appData
const { dispatch } = this.props
// if this await is commented out, function behaves perfectly
const foo = await this.resolveAfterSecond('bar')
//these two pieces of data are tightly coupled and must be updated together.
const activeNuggets = allNuggets.filter(nugget => nugget.domain === nextActiveDomain)
const activeTags = this.getTagsFromNuggets(activeNuggets)
//With the await statement above, there are renders in between these two actions
dispatch(batchActions([
this.props.actions.setNuggets({ nuggets : activeNuggets }),
this.props.actions.setTags({ tags : activeTags })
]))
}
@dgaitsgo That is truly perplexing. Are your setNuggets
or setTags
functions asynchronous? I can't imagine why this would split the actions. How are you creating your store?
I reproduced the problem,in my demo project
when I minus, it render one time; but when i add , it render four time;
it occur in Promise and SetTimeout;
I have the same feeling. Looking at batchDispatchMiddleware
, it seems that it fires store.dispatch
multiple times, which causes multiple renders.
Can confirm - using batchDispatchMiddleware
causes this problem, while using enableBatching
doesn't. Unfortunate, because I was reaching for batchDispatchMiddleware
as a way to detect / respond to the batched event itself in addition to the children, batched events.