Closed mvgijssel closed 2 years ago
Thanks for the PR! Introducing BehaviorSubject
there will be an extra initial forceUpdate
.
To prevent it I think we can give shouldUpdate$$
an extra state.
undefined
initial value. Do nothing.{ current: value }
new value.false
triggers forceUpdate
.What do you think? @mvgijssel
What do you think? @mvgijssel
Sounds good! To be clear, you want me to keep BehaiourSubject but prevent an unnecessary render by ignoring the initial undefined
In the callback responsible for triggering React?
Yes can you update the PR?
I've updated the PR and the associated tests, but it seems like that adding
} else if (valueRef === false) {
doesn't have an impact on the renderCount
in the specs. With or without it, when using BehaviorSubject the mentions it will render one additional time. Not sure how to prevent that, so updated the specs to reflect the additional render.
when using BehaviorSubject the mentions it will render one additional time
I think I know why. After the Suspense re-rendering, the component is re-created, the subscription is also re-established. It's fine with the good old Subject
but in the case of BehaviorSubject
there will be an initial false
value, so an extra re-render is triggered.
Ah yes makes sense! Can you approve the workflow run so we can get this merged? :)
maybe adding a resource.shouldUpdate$$.next(undefined)
before forceUpdate()
should fix this? Also please change the spec back.
maybe adding a
resource.shouldUpdate$$.next(undefined)
beforeforceUpdate()
should fix this? Also please change the spec back.
Nope. This will create race condition on multiple components consuming the same observable resource.
I'll merge this PR first and see if there are other workarounds for the optimization.
Fixed it by splitting valueRef$$
from shouldUpdate$$
. https://github.com/crimx/observable-hooks/commit/d97401262215ffd9295a2f4df2bdad19018f9e80
@mvgijssel Could you verify that this is working as expected? Or do you know how to add a test case for this?
observable-hooks@4.2.0 published.
Sorry for the late reply, holidays and such 🎉. But amazing that you got it fixed! I'll install the latest version and see if it works as expected.
I ran into a race condition using this library in combination with rxfire. The sequence of events:
useObservableSuspense(resource)
resource
returns the first value from the Firestore backendpackages/observable-hooks/src/use-observable-suspense.ts:19
useObservableSuspense
hook will setup a subscription on theshouldUpdate$$
observable atpackages/observable-hooks/src/internal/use-subscription-internal.ts:36
once the component is mounted.The race condition happens with step 5. If the
resource
receives the next piece of data before mounting is completed, theshouldUpdate$$
won't have a listener setup yet and this next piece of data is never rendered in the UI.One way of solving this problem is by using a BehaviourSubject. From the docs
I've also updated the
postinstall
hook to build the code so I can install this fork directly in my project adding the following line to mypackage.json
: