-
Notifications
You must be signed in to change notification settings - Fork 73
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
fix: connection could be called twice on set #570
fix: connection could be called twice on set #570
Conversation
Reviewer Checklist
Screenshots/VideosAndroid: Native2024-07-23.17.22.36.movAndroid: mWeb Chrome2024-07-23.16.58.23.moviOS: Native2024-07-23.16.53.52.moviOS: mWeb Safariios-web.movMacOS: Chrome / Safariweb.movMacOS: Desktopdesktop_3OwDY93A.mp4 |
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.
Changes look good to me too, waiting for a c+ testing
Co-authored-by: Vit Horacek <[email protected]>
lib/types.ts
Outdated
@@ -263,6 +263,11 @@ type Collection<TKey extends CollectionKeyBase, TValue, TMap = never> = { | |||
/** Represents the base options used in `Onyx.connect()` method. */ | |||
type BaseConnectOptions = { | |||
initWithStoredValues?: boolean; | |||
/** | |||
* If true, it will call the callback function even if the value might hasn't changed. |
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 think you left an error here, right? "Value might hasn't changed"
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.
Hm maybe my wording wasn't precise here.
When this value is true
it can happen that the Onyx.conenct callback gets called with the same value multiple times (basically bypass the improvement)
Do you have an idea how to rephrase it to make it more obvious / better understandable?
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.
Currently discussing if this param is really needed
hm, lets wait one moment before we continue, want to ask Fabio one thing who wrote the useOnxy hook. Maybe we don't need the |
The changes look good ! |
Yes, thanks for being patient with me! There was this test that failed with the changes I made: The thing is that the test case was a bit broken. In the test we change the selector function reference. In a react application that will only happen when the hook gets called again aka. the component re-renders (if we follow all strict rules, which we do). So the solution was to fix the test by simulating how in a regular react app the selector ref would change - with a |
@hannojg |
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.
Changes look good. No blockers from me.
tests/unit/useOnyxTest.ts
Outdated
@@ -276,6 +276,8 @@ describe('useOnyx', () => { | |||
expect(result.current[1].status).toEqual('loaded'); | |||
|
|||
selector = (entry: OnyxEntry<{id: string; name: string}>) => `id - ${entry?.id}, name - ${entry?.name} - selector changed`; | |||
// In a react app we expect the selector ref to change during a rerender (see selectorRef/useLiveRef) | |||
rerender(undefined); | |||
|
|||
await act(async () => Onyx.merge(ONYXKEYS.TEST_KEY, {id: 'changed_id', name: 'changed_name'})); |
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.
await act(async () => Onyx.merge(ONYXKEYS.TEST_KEY, {id: 'changed_id', name: 'changed_name'})); | |
await act(async () => waitForPromisesToResolve()); | |
expect(result.current[0]).toEqual('id - test_id, name - test_name - selector changed'); |
I think we can remove the Onyx.merge since the rerender() is enough to prove the selector changed
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.
ah good idea, let me check!
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.
We don't even need waitForPromisesToResolve() 😊 looks good?
@mountiny I think we are good to merge! |
🚀Published to npm in v2.0.58 |
@hannojg I noticed that these changes are causing some tests in E/App to fail. Is this expected?
|
They are failing due to another bug in Onyx for which I have a PR to fix here: |
Details
This PR fixes cases where a call to
Onyx.set
could invoke aOnyx.connect
listener twice.For
withOnyx
connections this isn't happening, as they are already guarded by previous equal comparisons.The fix here is to add a map that will store all previous values that were send to the
Onyx.connect
callback. We can't reuse the cache here unfortunately, as it can contain values while no data has been send to the connection yet (and thus a comparison would lead to us not sending to the connection.For useOnyx I had to add a special parameter to
Onyx.connect
calledalwaysNotify
which is false by default.useOnyx
might uses a selector to transform the data. The output of that selector can change, even though the input data stay the same.Thus for
useOnyx
we always have to call the connect callback.Related Issues
#569
Automated Tests
Manual Tests
n/a
Author Checklist
### Related Issues
section aboveTests
sectiontoggleReport
and notonIconClick
)myBool && <MyComponent />
.STYLE.md
) were followedAvatar
, I verified the components usingAvatar
are working as expected)/** comment above it */
this
properly so there are no scoping issues (i.e. foronClick={this.submit}
the methodthis.submit
should be bound tothis
in the constructor)this
are necessary to be bound (i.e. avoidthis.submit = this.submit.bind(this);
ifthis.submit
is never passed to a component event handler likeonClick
)Avatar
is modified, I verified thatAvatar
is working as expected in all cases)main
branch was merged into this PR after a review, I tested again and verified the outcome was still expected according to theTest
steps.Screenshots/Videos
Note: pressing the send button might be buggy in the recordings, its a know issue first reported here and is not related to this PR.
Android: Native
Screen.Recording.2024-07-22.at.13.11.30.mov
Android: mWeb Chrome
Screen.Recording.2024-07-22.at.12.53.24.mov
iOS: Native
Screen.Recording.2024-07-22.at.12.46.08.mov
iOS: mWeb Safari
iOS-mWeb.mov
MacOS: Chrome / Safari
web.mov
MacOS: Desktop
desktop.mov