unimplement shouldComponentUpdate?
See original GitHub issueThere was some good discussion on Twitter (between @gaearon, @markerikson, @timdorr, @mjackson, @ryanflorence, et al.) about connect
’s component implementing shouldComponentUpdate
.
If I understand correctly, the main issue being that any component wrapped in connect
then blocks updates related to context changes, and this has an adverse impact on libraries that pass data via context that need to trigger rerenders (such as React Router’s Link component.)
The changes in the next
branch of React Redux make its implementation of shouldComponentUpdate
much less necessary, mainly because now setState
is no longer called as a response to every store state change, but only if the final merged props have changed. So now when shouldComponentUpdate
is called as a result of calling setState
, it’s always going to return true anyways. (The call to setState could probably be replaced with forceUpdate and would work exactly the same.)
In the case of shouldComponentUpdate
being called after receiving new props from parent, it’s effectively just acting like PureComponent
. That responsibility can be given to the components being wrapped, which would have better knowledge about if/how they should implement shouldComponentUpdate
. I personally would use recompose and do something like:
export default compose(
pure, // <-- from recompose
connect(...),
)(MyComponent);
An alternative to removing connect’s shouldComponentUpdate
completely would be to make it an another option
argument, and decide whether it should be opt-in or opt-out.
Issue Analytics
- State:
- Created 7 years ago
- Reactions:25
- Comments:23 (18 by maintainers)
Top GitHub Comments
Just to be clear and make sure everyone understands what’s going on, here is the situation with something like react-redux and React Router:
In this case,
<Router>
is providing a context that<Link>
is consuming something like this:(That’s a crazy over-simplification, but it gets the point across)
If the URL/location on the page changes, then that information should propagate from the
<Router>
to the<Link>
viathis.context
, causing it to potentially re-render. Context is a way to cross the boundaries of direct Component-to-Component communication via props.The problem lies with
shouldComponentUpdate
not being able to take into account changes onthis.context
. Theconnect()
ed component thinks nothing has changed with its props during this time (which is true!), so it tells React that it shouldn’t re-render this component (or anything underneath it, including the<Link>
!).Hopefully that explains the situation well enough. How to fix it is another matter 😃
Oh boy, this oughta be good… 😃