【问题标题】:How do I render a div and script tags in React?如何在 React 中渲染 div 和 script 标签?
【发布时间】:2021-02-25 11:58:36
【问题描述】:

react 应用程序收到一个可视化代码,我使用 unescape 函数获取字符串中的 HTML 代码。该字符串有一个 div 标记,其中包含可视化的 id 和 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>
  );
}

这里我提供了codesandbox链接

我使用dangerouslySetInnerHtml 显示可视化但无法可视化图表。我在公共文件夹中添加了一个 test.html 以在浏览器中显示可视化。非常感谢任何帮助。

【问题讨论】:

    标签: javascript reactjs html-react-parser


    【解决方案1】:

    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

    顺便说一句。请不要使用“unes​​cape”,它已被弃用。请改用“decodeURIComponent”。

    【讨论】:

      【解决方案2】:

      好的,这个答案可以满足你的要求,但我不得不说:只有在你 100% 知道 vizCode 的来源并且可以信任的情况下才使用它! be sure to check out the reasons why you should not use 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>
        );
      }
      

      【讨论】:

        【解决方案3】:

        我不确定它是否满足您的要求,但您可以使用window.openiFrame 或新标签中呈现 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");
        

        【讨论】:

          【解决方案4】:

          试试:

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2018-05-07
            • 2017-08-08
            • 1970-01-01
            • 1970-01-01
            • 2019-05-17
            • 2012-01-14
            • 1970-01-01
            相关资源
            最近更新 更多