PSA: Vite bundler HMR re-render bug
hughdtt opened this issue · comments
Hugh Duong-Tran-Tien commented
PSA for those following the React bootstrap instructions on site documentation
Issue: Vite's hot module reloader doesn't clean up React DosPlayer component properly
Context:
-
New to js-dos, so I decided to follow the React bootstrap instructions https://js-dos.com/v7/build/docs/react/ in the doco but using Vite instead.
-
Ran into the issue where the dos player component was re-rendering itself on every save, but only re-rendering once on first load.
-
I'd get stuck with something like this
- Thought it was weird since the code provided already had an
instance.stop()
for cleanup.
Fix:
- Turns out Vite HMR works differently from whatever bundler was intended.
- You'll need to add a
root.innerHTML = '';
to the DosPlayer return function to make sure it's cleaning up on every render properly.
Typescript component ends up looking a little like this:
import React, { useEffect, useRef, useState } from "react";
import { DosPlayer as Instance, DosPlayerFactoryType } from "js-dos";
declare const Dos: DosPlayerFactoryType;
interface PlayerProps {
bundleUrl: string;
}
export default function DosPlayer(props: PlayerProps) {
const rootRef = useRef<HTMLDivElement>(null);
const [dos, setDos] = useState<Instance | null>(null);
useEffect(() => {
if (rootRef.current === null) {
return;
}
const root = rootRef.current as HTMLDivElement;
const instance = Dos(root);
setDos(instance);
return () => {
instance.stop();
root.innerHTML = ''; //fix
};
}, [rootRef]);
useEffect(() => {
if (dos !== null) {
dos.run(props.bundleUrl); // ci is returned
}
}, [dos, props.bundleUrl]);
return <div ref={rootRef} style={{ width: "100%", height: "100%" }}></div>;
}
End of the day, it's not a js-dos issue but a weird interaction with Vite.
Just thought it might be helpful for people who run into the same issue. It gave me a headache far longer than it should have 🤣
Good day
Alexander Guryanov commented
Wow. Thank you very much, I think we need to add this to docs. Cleaning the DOM tree is good idea in any case.