Component not reloading #326
-
Hi, I have a hot observable based on a web socket the emits event irregularly. I pre-subscribe to keep it hot. I have a small component that show the latest value. I uses the bind, and should then reload when new emits are received. It does so most of the time but not consistently, sometime it just skip a reload. It seems total random. It can reload on an emit, then when the next emit comes after several seconds it does not reload. And when after several additional seconds one more emit arrives it does reload again. Here is my code: import './App.css'
import {bind, Subscribe} from "@react-rxjs/core";
import {ErrorBoundary, FallbackProps} from "react-error-boundary";
import {map, mergeMap, Observable} from "rxjs";
import {webSocket} from "rxjs/webSocket";
const emit$: Observable<number> = webSocket<Array<Array<never>>>("http://localhost:8000/emits/stream").pipe(
mergeMap(l => l), map(e => e[2])
)
const [emit, emit$$] = bind(emit$)
emit$$.subscribe(e => {console.log("emit", e)})
function ErrorFallback({ error, resetErrorBoundary }: FallbackProps) {
return (
<div>
<p>Something went wrong:</p>
<pre>{error?.message}</pre>
<button onClick={resetErrorBoundary}>Try again</button>
</div>
)
}
const EmitValue: React.FC = () => {
console.log("EmitValue");
const [emitValue] = bind(emit$$.pipe(map(e => {
console.log("got", e);
return e
})))
return (<div>{emitValue()}</div>)
}
function AppDemo() {
return (
<>
<ErrorBoundary FallbackComponent={ErrorFallback}><Subscribe>
<EmitValue/>
</Subscribe></ErrorBoundary>
</>
)
}
export default AppDemo; Here is some console log
In this example the component did not reload for the -75 value. The -72 did also not do a reload, but it was almost immediately followed by the -71 value, so that was properly ok. I do think it is very strange that the "got" logs several times for each emit, but it does not seem directly related to the missing reloads. I would very much appreciate some help, thank you :-) |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments
-
Yes, there's a bit of misunderstanding on how this library should be used and react itself
The convention in React is to name your hooks starting with const emit$: Observable<number> = webSocket<Array<Array<never>>>("http://localhost:8000/emits/stream").pipe(
mergeMap(l => l), map(e => e[2])
)
const [useEmission, emit$$] = bind(emit$)
emit$$.subscribe(e => {console.log("emit", e)})
const EmitValue: React.FC = () => {
const emissionValue = useEmission();
console.log("got", emitValue);
return (<div>{emissionValue}</div>)
} Give this a try, let me know if it works. You might get multiple "got" logs per each "emit", because React sometimes will call the component function multiple times. |
Beta Was this translation helpful? Give feedback.
-
Got it! Thank you so much for your very nice answer! |
Beta Was this translation helpful? Give feedback.
Yes, there's a bit of misunderstanding on how this library should be used and react itself
bind
returns two things: A hook to use the value in a React component, and a shared stream to keep composing with other streams.bind
should never be called inside a react component. You call it outside just once, grab the hook and use it inside your component.The convention in React is to name your hooks starting with
use
, so your example should become: