-
Notifications
You must be signed in to change notification settings - Fork 4.2k
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
components: Stop modifying the parent context and correctly memoize it #32745
Conversation
Size Change: -14 B (0%) Total Size: 1.04 MB
ℹ️ View Unchanged
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for looking into this! It definitely feels like a step in the right direction, but after a quick check it doesn't seem to fix all of the issues that I flagged in #32743
Fixed:
- The context "leak" problem
Still not fixed:
- The inner most
Card
doesn't seem to inherit values from the outer context (e.g. the innermost card doesn't have anelevation
of 10 - When swapping from
ui/card
tosrc/card
, the values defined in the story's context still don't seem to apply to theCard
components
@sarayourfriend can you reproduce this same behaviour?
I can reproduce this problem. I'll see if I can fiddle with it tomorrow to discover what's going on. This might just be the actual expected behavior of the context system, I'm not sure. |
|
||
if ( ! isEqual( value, valueRef.current ) ) { | ||
valueRef.current = value; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It turns out this was the problematic line that was causing the context to not get merged correctly. Becuase valueRef
was being assigned to the merged value, value and valueRef.current were never going to be equal if the parent context included anything.
We're able to avoid this comparison altogether if we make a guarantee that value and parent context are memoized however, so the new version of this hook is able to avoid this complexity completely.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tested by applying to #32743 and it worked great 🎉 Great job!
I left a couple of minor comments, but this PR is good to go after they are addressed and the conflicts are solved
}, [ value, parentContext ] ); | ||
// parent context will always be memoized or the default value (which will not change) | ||
// so this memoization will prevent `merge` and `cloneDeep` from rerunning unless | ||
// the referneces to value change. The `useUpdateEffect` above will ensure that we are |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// the referneces to value change. The `useUpdateEffect` above will ensure that we are | |
// the references to value change. The `useUpdateEffect` above will ensure that we are |
setConfig( ( prev ) => ( { ...prev, ...valueRef.current } ) ); | ||
} | ||
}, [ value, parentContext ] ); | ||
// parent context will always be memoized or the default value (which will not change) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure I follow completely the meaning of the first 2 sentences, would you mind articulating a bit better?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried to re-write this/add more details, but I'm not sure it actually is helpful. Let me know what you think.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Much better!
It's important that this function's implementation is well commented, since it's very dense and empowers the whole context system. Thank you!
d1910b8
to
db4da2c
Compare
Description
This fixes a bug in the
ContextSystemProvider
where the parent context was being modified by themerge
function which is not a pure function (hello lodash 😱). By cloning the parent context we ensure that it will not be modified and therefore spread throughout the app.To test this apply this patch to #32743 and ensure that you can no longer reproduce the bug described by @ciampo.
Note: if this becomes a performance concern we can always switch to using the
deepmerge
package which exports a pure function. It's very fast and very small dependency. May be worth it if we find this to be a perf issue.How has this been tested?
Apply the patch to the PR described above.
Types of changes
Bug fix
Checklist:
*.native.js
files for terms that need renaming or removal).