Как визуализировать теги div и script в React?

Приложение реакции получило код визуализации, и я использовал функцию unescape, чтобы получить коды HTML в виде строки. Строка имеет div тег с идентификатором визуализации и script тег, который состоит из javascript для создания визуализации.

      import React from "react";
import parse from "html-react-parser";

export default function App() {
  // This code is received from the backend
  const vizCode =
    "%3Cdiv%20id%3D'chartdiv_1614071920146'%3E%3C%2Fdiv%3E%3Cscript%20type%3D'text%2Fjavascript'%3E%20var%20width_1614071920146%20%3D%20700%3Bvar%20height_1614071920146%20%3D%20700%3Bvar%20chart_1614071920146%20%3D%20c3.generate(%7Bbindto%3A%20'%23chartdiv_1614071920146'%2C%20size%3A%20%7B%20width%3A%20(width_1614071920146%20-%2020)%2C%20height%3A%20(height_1614071920146%20-%2020)%20%7D%2C%20data%3A%20%7Bcolumns%3A%20%5B%20%5B'%20'%2C%201.0%2C%201.0%2C%203.0%2C%205.0%2C%205.0%5D%20%5D%2C%20type%3A%20'spline'%7D%2C%20legend%3A%20%7Bshow%3Afalse%7D%2C%20axis%3A%20%7B%20x%3A%20%7B%20type%3A%20'category'%2C%20categories%3A%20%5B'New%20Course'%2C'group%20course%201'%2C'Testkurs%20'%2C'test_course'%2C'Moodle4CollaborativeMOOCs'%5D%20%7D%20%7D%7D)%3B%3C%2Fscript%3E";
  const unescapedVizCode = unescape(vizCode);
  console.log(unescapedVizCode);
  // Output -> <div id='chartdiv_1614071920146'></div><script type='text/javascript'> var width_1614071920146 = 700;var height_1614071920146 = 700;var chart_1614071920146 = c3.generate({bindto: '#chartdiv_1614071920146', size: { width: (width_1614071920146 - 20), height: (height_1614071920146 - 20) }, data: {columns: [ [' ', 1.0, 1.0, 3.0, 5.0, 5.0] ], type: 'spline'}, legend: {show:false}, axis: { x: { type: 'category', categories: ['New Course','group course 1','Testkurs ','test_course','Moodle4CollaborativeMOOCs'] } }});</script> 

  let objectData = parse(unescapedVizCode);
  let divData = objectData[0];
  let scriptData = objectData[1].props.dangerouslySetInnerHTML.__html;

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

Здесь я предоставил ссылку на коды и ящик

Я использовал dangerouslySetInnerHtmlчтобы отобразить визуализацию, но невозможно визуализировать диаграмму. Я добавил test.html в общую папку, чтобы показать визуализацию в браузере. Любая помощь горячо приветствуется.

4 ответа

Решение

React / JSX не работает с тегами скриптов. Вы должны явно загрузить его. Я предлагаю вам использовать ловушку, когда компонент доступен.

        useEffect(() => {
    const script = document.createElement('script');
    script.innerHTML = scriptData;
    document.getElementById('root').appendChild(script);
    return () => {
      document.getElementById('root').removeChild(script);
    };
  }, []);

Рабочий пример здесь: https://codesandbox.io/s/render-c3d3-charts-in-react-forked-4xkt9?file=/src/App.js

Кстати. Пожалуйста, не используйте unescape, это не рекомендуется. Вместо этого используйте decodeURIComponent.

Хорошо, этот ответ делает то, что вы хотите, но я должен сказать: используйте его только в том случае, если вы на 100% знаете, откуда берется vizCode, и что ему можно доверять! обязательно ознакомьтесь с причинами, по которым вам не следует использовать eval

Ваша проблема в том, что содержимое скрипта не выполняется браузером. Я попробовал вашу песочницу, и она сразу сработала, когда я добавил

      eval(scriptData)

Вот весь код, который у меня работает:

      export default function App() {
  // This code is received from the backend
  const vizCode =
    "%3Cdiv%20id%3D'chartdiv_1614071920146'%3E%3C%2Fdiv%3E%3Cscript%20type%3D'text%2Fjavascript'%3E%20var%20width_1614071920146%20%3D%20700%3Bvar%20height_1614071920146%20%3D%20700%3Bvar%20chart_1614071920146%20%3D%20c3.generate(%7Bbindto%3A%20'%23chartdiv_1614071920146'%2C%20size%3A%20%7B%20width%3A%20(width_1614071920146%20-%2020)%2C%20height%3A%20(height_1614071920146%20-%2020)%20%7D%2C%20data%3A%20%7Bcolumns%3A%20%5B%20%5B'%20'%2C%201.0%2C%201.0%2C%203.0%2C%205.0%2C%205.0%5D%20%5D%2C%20type%3A%20'spline'%7D%2C%20legend%3A%20%7Bshow%3Afalse%7D%2C%20axis%3A%20%7B%20x%3A%20%7B%20type%3A%20'category'%2C%20categories%3A%20%5B'New%20Course'%2C'group%20course%201'%2C'Testkurs%20'%2C'test_course'%2C'Moodle4CollaborativeMOOCs'%5D%20%7D%20%7D%7D)%3B%3C%2Fscript%3E";
  const unescapedVizCode = unescape(vizCode);
  console.log(unescapedVizCode);

  let objectData = parse(unescapedVizCode);
  let divData = objectData[0];
  let scriptData = objectData[1].props.dangerouslySetInnerHTML.__html;
  useEffect(()=>{
    eval(scriptData)
  }, [scriptData])
  return (
    <div className="App">
      {objectData}

    </div>
  );
}

Я не уверен, удовлетворяет ли он вашим требованиям, но вы можете использовать window.open для отображения HTML-кода внутри или на новой вкладке.

Открыть в iFrame используйте следующий код:

      const unescapedVizCode = unescape(vizCode);
window.open(unescapedVizCode, "myFrame");
return (
<div className="App">
<iframe name="myFrame"></iframe>
  {objectData}
</div>
);

Или вы можете открыть в новой вкладке:

      const unescapedVizCode = unescape(vizCode);
window.open(unescapedVizCode, "_blank");

Пытаться:

      let objectData = parse(`<div className="App">${unescapedVizCode}</div>`);

return objectData;
Другие вопросы по тегам