In a React + Redux based project, I have a connect()
ed component which checks user permissions via an API fetch. Fetched permissions are stored in the Redux store.
The component basically looks like <Can check="...">...</Can>
, which talks to our API (via Redux actions) to resolve the check. If the permission is granted, this.props.children
is rendered, null
otherwise.
For that, mapStateToProps()
computes a passes
prop from authorization data in the store, which is checked in <Can />
s render()
method. I utilize the ownProps
parameter to mapStateToProps()
to get the "stuff to check" and compute the passes
flag.
There's a bit of caching going on so I don't re-fetch on every component mount, and it basically works. Sometimes, though, the component will not re-render when the passes
prop updates to true
(it will however render after navigating away - using react router - and back again, so basically if the component is re-mounted).
Do connect()
ed components re-render if the output from mapStateToProps()
changes? The docs for react-redux
's connect()
say this:
If ownProps is specified as a second argument, its value will be the props passed to your component, and mapStateToProps will be re-invoked whenever the component receives new props.
Does that mean that passing in ownProps
changes the rendering to only re-render if props change, or in any other way? How can I understand the note regarding memoization/returning a function from mapStateToProps()
, or is that not even related?
Thank you
Do connect()ed components re-render if the output from mapStateToProps() changes? The docs for react-redux's connect() say this:
Output from a function can’t change by itself. Something must trigger this function to be re-evaluated in the first place.
If Redux state changes, mapStateToProps
is re-evaluated.
If props received from parent component are shallowly unequal (have changed) and you use ownProps
argument, mapStateToProps
is also re-evaluated.
If mapStateToProps
returned shallowly equal values to its last call, then React Redux will skip rendering. If it returned shallowly unequal values, the wrapped component will be re-rendered. It is assumed that mapStateToProps
itself is a pure function.
Sometimes, though, the component will not re-render when the passes prop updates to true
Please create a minimal project reproducing this and file an issue with the relevant code example.
How can I understand the note regarding memoization/returning a function from mapStateToProps(), or is that not even related?
Not related.
Several things to know here:
connect
will shallow-compare the output of the last mapState
call to the current mapState
call. If nothing changed, it will not re-render the wrapped component.connect
will only run mapState
when the store notifies subscribers. However, if your mapState
function is declared as taking two parameters, connect
will pass in the wrapped component's props as the second arg, allowing you to do things like state.somePerItemData[ownProps.itemId]
. It also then calls mapState
any time the incoming props differ, as that may affect the output of mapState
.mapState
argument, which could create a unique selector function instance for each component instance.All that said, I'm afraid I don't have a specific answer for your actual question about the component not updated. I'd probably need to see the code in more detail.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With