React functional component stops rendering on state changes after remounting

Viewed 82

Any suggestions with this strange situation would be greatly appreciated.

I have a parent component that listens to the callback status from a child component, and renders a progress indicator based on the status. The child component is an editor and uses memo to prevent re-rendering. This is required by the editor package. Everything works fine when the parent and child are fist mounted, but if the parent is unmounted and remounted, it doesn't render the state changes triggered by the child callback.

I've tried various things to force a re-rendering, but nothing seems to work. I added a counter to the state and a delay on updating the state. I use ref as a value since the state is being accessed in a closure.

The child component is an editor that listens to websocket information and calls handleStatus callback asynchronously. The child component is working fine after the remount and sending the updates to the handleStatus callback.

Parent Component:

const [isConnected, setIsConnected] = useState<number>(0);
const forceUpdate = useRef<number>(0);
const statusRef = useRef('connected')


const handleStatus = (status: string) => {

    if ('connected' !== status) {
        forceUpdate.current += 1;
        setTimeout(()=>{
            setIsConnected(forceUpdate.current);
        }, 100)
        statusRef.current = status;
    } 
}

<div style={{width: '100%'}} >
      {statusRef.current === 'connected' ? null : <CircularProgress />}
      <ChildComponent key={roomId} roomId={roomId} handleStatus={handleStatus}/>
</div>

From the debugger, I can see that handleStatus is being called and setIsConnected is being called with a new value. But the parent does not render when the state is changed.

Again, the parent only stops listening to the state updates after it was remounted. On the first mount, the parent renders on every state update.

Any suggestions where to look would be greatly appreciated.

Edit: I'm using the same key for the parent component, so react should remount the existing component instead of creating a new component. From what I can see, it does look like it's remounting the same component since the ref retains its value and the callback from the child component is still valid. The state value is stale, but that's expected since it's in a closure. The only thing that's not making sense is that I can't seem to trigger a rerender by updating the setState. I even tried a state function incase the setState was getting stale too, but that didn't work either.

1 Answers

you need to use useEffect and as dependency put statusRef variable

useEffect(() => {
    
}, [statusRef])

<ChildComponent key={roomId} roomId={roomId} handleStatus={handleStatus}/>
Related