Use transactional setState() inside connect()
See original GitHub issueWe currently delay calling mapStateToProps
and mapDispatchToProps
in the common case because it is too early to supply ownProps
inside handleChange
, as those props may themselves be obtained from the previous version of the state by the parent component, and may not have been received as the new props just yet, so we bump into issues with staleness (#86).
Right now we call them inside render()
so ownProps
are always up-to-date but this is a bit odd, makes the code complicated and in some cases robs us of possible performance improvements, as caching the element isn’t quite as good as providing shouldComponentUpdate
(#366).
One possible solution to this would be to use the transactional setState()
overlord overload.
It is described in the documentation:
It’s also possible to pass a function with the signature function(state, props). This can be useful in some cases when you want to enqueue an atomic update that consults the previous value of state+props before setting any values. For instance, suppose we wanted to increment a value in state:
setState(function(previousState, currentProps) { return {myInteger: previousState.myInteger + 1}; });
This looks pretty much exactly like our use case, and I have a feeling that this would let us use setState
normally without having to resort to calling mapStateToProps
and friends in render()
. In this case, we would probably keep the merged props rather than the store state, in the local state.
We still want to keep the “fast path” that avoids setState
altogether in handleChange
, but other than that, the rest of the code should be vastly simplified by this, or at least become more conventional.
I’m still not 100% sure this is going to work, but I encourage anyone who wants to dig deeper into how React and Redux work together to give this a try. We have an extensive test suite that should cover any call count regressions. If you are working on this, please leave a comment in this issue.
Issue Analytics
- State:
- Created 7 years ago
- Reactions:7
- Comments:8 (4 by maintainers)
Top GitHub Comments
Looking into it! I’m trying to wrap my head around what would no longer be necessary. Looks like this could clean up quite a bit of hand holding around
haveStatePropsBeenPrecalculated
and stateProps inrender()
.Really happy to see all those red lines on first commits 😃