hook returned by bind(functionAcceptingArrayReturningAsyncObservable$) should not cause infinite render loop
Closed this issue · 2 comments
Observed Behavior
Given
- a function
getAsyncObservableFromArray$(words: string[])
that returns an asynchronous observable - a
use...
hook that is derived from aforementioned function - a React component that invokes the aforementioned hook function
... the component causes an infinite render loop.
Expected Behavior
There should be no infinite render loop, the behavior should be no different from a similar scenario with
- a function
getObservableFromArray$(words: string[])
that returns a synchronous observable - a function
getAsyncObservableFromScalar$(word: string)
that returns an asynchronous observable
Steps to Reproduce
Uncomment line 35 in App.tsx in this code sandbox
Hey Bruce, thank you for your report!
However, this is intended behaviour. The parameters on a bind
are meant to give you an observable for one specific instance, so they need to be identifying - and ReactRxJS uses referential equality.
The problem here is that because on every render you're creating a new array, bind
will understand you have just switched to another instance of the observable. So it will unsubscribe from the previous one, call the factory function again (passing in the new array), and it will subscribe to the new observable returned by that function.
Because it's asynchronous, the hook will trigger suspense and when the value comes back, it will set the state. Which causes a re-render, which starts the cycle over again (a new array is created, bind understands it's a new instance, etc.)
The way to work around that depends a lot on your specific case, but usually it's moving the parameter you want to pass to the observable into another state observable, and then referencing that from your bind
.
Thanks very much @voliva for the excellent explanation, much appreciated!