caiiiycuk / js-dos

The best API for running dos programs in browser

Home Page:https://js-dos.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

PSA: Vite bundler HMR re-render bug

hughdtt opened this issue · comments

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

image

  • 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

Wow. Thank you very much, I think we need to add this to docs. Cleaning the DOM tree is good idea in any case.