Comment intégrer du JavaScript brut (vanille) dans ReactJS?

Oct 01 2020

J'essaye d'utiliser cette visualisation 3D gio dans mon application ReactJs. Le code est écrit en JavaScript vanille. J'ai également trouvé un wrapper pour React et l'ai essayé mais je ne suis pas en mesure de choisir le pays sélectionné ( onCountryPicked()) comme il est montré sur leur démo . C'est la raison principale pour laquelle je continue avec l'implémentation de JavaScript vanilla au lieu de wrapper. Cependant, je trouve l'implémentation JavaScript vanilla difficile à intégrer à mon application ReactJs.

J'ai cherché à résoudre le problème, mais les ressources que j'ai trouvées ne m'ont pas aidé. Voici quelques-uns des endroits que j'ai visités.

  • Comment utiliser le javascript vanille dans le composant Reactjs?
  • https://reactjs.org/docs/integrating-with-other-libraries.html

helloworld.js

var container = document.getElementById("globalArea");

var controller = new GIO.Controller(container, {
  color: {...},
  brightness: {...},
});

controller.onCountryPicked(callback);
controller.setInitCountry("FR");
controller.showOutOnly(false);
controller.showInOnly(false);

function callback(selectedCountry) {
  $("#countryArea").text(selectedCountry.name + " picked!"); $("#infoBoard").fadeIn(300);
  setTimeout(function () {
    $("#infoBoard").fadeOut(1000); }, 3000); } axios .get("./test_data.json") .then(function (response) { controller.addData(response.data); }) .catch(function (error) { console.log(error); }) .then(function () { controller.init(); }); var d3Graphs = { tiltBtnInterval: -1, }; function showHud() { $("#hudButtons").show();
  $(".tiltBtn").on("mousedown touchstart", d3Graphs.tiltBtnClick); $(".tiltBtn").on("mouseup touchend touchcancel", d3Graphs.tiltBtnMouseup);
}

function tiltBtnClick() {
  var delta;
  if ($(this).hasClass("sideViewBtn")) {
    delta = 10;
  } else {
    delta = -10;
  }
  d3Graphs.doTilt(delta);
  d3Graphs.tiltBtnInterval = setInterval(d3Graphs.doTilt, 50, delta);
}

function doTilt(delta) {
  tilt += delta * 0.01;
  tilt = constrain(tilt, 0, Math.PI / 2);
  camera.position.y = 300 * Math.sin(-tilt);
  camera.position.z = 100 + 300 * Math.cos(-tilt);
  camera.lookAt(new THREE.Vector3(0, 0, 300));
  tiltTarget = undefined;
}

............

home.html

<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <script src="./lib/jquery-3.3.1.min.js"></script>
    <script src="./lib/three.min.js"></script>
    <script src="./lib/gio.min.js"></script>
    <script src="./lib/axios.min.js"></script>
    <script src="https://d3js.org/d3.v5.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/apexcharts"></script>
    <link rel="stylesheet" href="helloworld.css" />
  </head>

  <body>
    <div class="b">
      <div id="infoBoard">
        <div id="countryArea"></div>
        <div id="explanation">Infos here</div>
      </div>
      <script src="helloworld.js"></script>
    </div>
  </body>
</html>

................

Sample.js

export class Sample extends React.Component {
  componentDidMount() {
  
  }

  render() {
    return (
      <div className="App">
         ...
      </div>
    );
  }
}

Réponses

2 LionelRowe Oct 04 2020 at 18:50

Voici un point de départ. J'ai annoté les parties où React interagit avec Gio.js.

const Globe = () => {
  // use a React ref whenever you need to directly target a DOM element
  // - this is required as an argument to the GIO.Controller constructor
  const ref = useRef(null);
  const [country, setCountry] = useState(initCountry);

  useEffect(() => {
    // useEffect with empty dependency array
    // - this will run once when the component mounts
    const controller = new GIO.Controller(ref.current, {
      control: {
        initCountry
      }
    });

    // import and add data here if you want the glowing lines
    controller.addData([]);

    controller.init();

    // here's the callback for when the user clicks a country
    // we can use the React setState hook inside the callback
    controller.onCountryPicked((country) => {
      setCountry(country.ISOCode);
    });
  }, []);

  return (
    <>
      <div>
        <strong>Selected country: {displayName.of(country)}</strong>
      </div>
      <div style={{ height: 500 }} ref={ref}></div>
    </>
  );
};

Démo CodeSandbox

PsiKai Oct 01 2020 at 17:56

Si vous mettez votre fichier javascript vanilla au même niveau hiérarchique que le vôtre index.htmlet que vous le liez normalement, vous devriez pouvoir implémenter votre javascript vanilla sans interférer avec votre javascript réactif. Reliez-le simplement en bas comme d'habitude avec une <script>balise.

Alternativement, à utiliser useStatedans votre code de réaction:

import React, {useState} from "react";
import ReactDOM from "react-dom";

const Country = () => {
  const [country, setCountry] = useState('');

  ///your javascript here

  setCountry(//return from javascript function// );

  return (
     <h1>{country}</h1>
  )
}

ReactDOM.render(<Country/>, document.getElementById("countryArea"));

Vous devrez importer toutes les dépendances supplémentaires pour votre javascript vanilla (ex. axios) Dans ce fichier.