-
Notifications
You must be signed in to change notification settings - Fork 11
Stale props issue in selector API #22
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
it('ensures consistency of state and props in selector', () => {
let selectorSawInconsistencies = false
const Parent = () => {
const count = useReduxState()
return <Child parentCount={count + 1} />
}
const Child = ({ parentCount }) => {
const result = useReduxState(count => {
selectorSawInconsistencies = selectorSawInconsistencies || (count !== parentCount)
return count + parentCount;
})
return <div>{result}</div>
} Are you sure we need |
@dai-shi yeah, that was from an old version of that test. Just pass |
Thanks! |
For the first test, I forgot to add try-catch, even though I saw the code in the other issue. For the second one, I'm not sure if this is really a blocking issue. If we allowed a selector to access global variables, there could be other issues not related to stale props. (and I remember I saw many impure selector code out there...) But anyway, I understand react-redux needs to care a lot about backward compatibility. |
@MrWolfZ the reference commit: ff9957b |
@dai-shi In general I think the heuristic to simply force components that get rendered first to be updated first should work out, except in concurrent mode. Concurrent mode means two major issues I can see:
Not being able to use batching could also lead to performance issues. |
Thanks. Yeah, I'm pretty sure it doesn't work in concurrent mode.
With the heuristical list, we can do the same like this, can't we?
Oh, you are right. There can be a memory leak even if we useRef. |
No, I don't think we can properly do this since we don't know the tree shape and therefore would have issues updating the component tree optimally. Let's quickly discuss why notifying children is even required. When a connected component is notified of a change, this usually leads to its children being re-rendered (in which case notifying children is not even required), but in the case there is for example a non-connected memoized component in the component's subtree, this could prevent children from properly re-rendering. So, in most cases this leads to a single DOM update that processes the store update completely, but to handle the edge cases react-redux notifies the children after the DOM changes are committed. Let's illustrate the usual case with an example component tree: <Root>
<A>
<AA />
</A>
<B>
<BB />
</B>
</Root> In this case, let's say Now let's see how this would work with a linear list of fingerprints. Since we don't know whether fingerprints later in the array are children or siblings we simply have to defer updating all fingerprints later in the list until after the current component is committed. This means for the example above that first, |
This totally explains. Thanks a lot. While you are here, do you think react-redux v7 accepts this stale props issue as a limitation of hooks api? I think your proposal is the best so far and it's silly to introduce hoc to solve the stale props issue. It would have been nice if the state context (aka v6) were possible, but it not likely to happen in the foreseeable future. |
I guess the discussion in reduxjs/react-redux#1252 explains it. So, in conclusion, our @faceyspacey You asked somewhere for the clarification, here it is. |
Thanks so much to reduxjs/react-redux#1179 (comment), it explains better to understand.
So, as long as we use
useReduxState()
, we are safe, but with selectors there could be inconsistencies. In our case, it'suseReduxSelectors()
.The text was updated successfully, but these errors were encountered: