h5p-standalone icon indicating copy to clipboard operation
h5p-standalone copied to clipboard

Ploblem on reRender on REACTJS

Open epsilon11101 opened this issue 1 year ago • 3 comments

each time that i want to re render a new component the component is appended on wrapper container

i use this when i want to re render other component maybe you can implement the code to validate is there are code on the main wrapper

     const hasChildren = h5pRef.current.children;
      if (hasChildren.length !== 0) {
        const parent = hasChildren[0].parentNode;
        parent.removeChild(hasChildren[0]);
      }

to understand you can see my own code:

App.jsx:

import Game from "./components/Game";
import { useEffect, useState } from "react";

const App = () => {
  const [currentGame, setCurrentGame] = useState(0);

  const games = ["cuestionario", "h5p-folder"];

  const showNewGameHandler = () => {
    if (currentGame <= 1) {
      setCurrentGame(currentGame + 1);
    } else {
      setCurrentGame(0);
      window.location.reload();
    }
  };

  return (
    <>
      <Game name={games[currentGame]} id={currentGame} />
      <button onClick={showNewGameHandler}>siguiente</button>
    </>
  );
};

export default App;

GameComponent

import { useEffect, useRef } from "react";
import { H5P as H5PStandalone } from "h5p-standalone";

const Game = ({ name, id }) => {
  let firstTime = true;
  const componentConfig = {
    h5pJsonPath: `/${name}`,
    frameJs: "/assets/frame.bundle.js",
    frameCss: "/assets/styles/h5p.css",
  };

  const h5pRef = useRef(null);

  const loadH5PComponent = async () => {
    if (h5pRef.current) {
      await new H5PStandalone(h5pRef.current, componentConfig);

      window.H5P.externalDispatcher.on("xAPI", (event) => {
        //do something useful with the event
        console.log("results:", event.getScore(), "---->", name);
      });
    }
  };

  useEffect(() => {
    if (firstTime) {
      const hasChildren = h5pRef.current.children;
      if (hasChildren.length !== 0) {
        const parent = hasChildren[0].parentNode;
        parent.removeChild(hasChildren[0]);
      }

      loadH5PComponent();
      firstTime = false;
    }
  }, [name]);

  return <div id={`h5p-container-${id}`} ref={h5pRef} />;
};

export default Game;

Maybe yo can implement this solution as below

File: h5p-standalon.ts
Method : renderPLayerFrame
line: 131 apox

suggested code:

    if (params.embedType === "iframe") {
      const divWrapper = document.getElementsByClassName("h5p-iframe-wrapper");
      if (divWrapper.length !== 0) {
        const parentWrapper = divWrapper[0].parentNode;
        parentWrapper.removeChild(divWrapper[0]);
      }

epsilon11101 avatar Jul 13 '23 21:07 epsilon11101