javascript - 有没有办法在 React 中将纯 HTML 作为单独的组件动态加载?
问题描述
嗨,我试图将烧瓶应用程序与反应前端结合起来。该项目主要专注于使用 pandas 和 matplotlib 等库的数据科学。我试图返回一个与 matplotlib fig 等效的 HTML,并试图在前端呈现它。
由于它是纯 HTML 而不是 JSX,因此当 react 尝试渲染它时会引发错误。在纯 html 设置中运行时,HTML 可以完美运行。我尝试了多个库,但未能在反应基础设置中呈现无花果。
我尝试的另一种方法是创建一个单独的元素,使用文档模型单独呈现 HTML,但由于该图稍后出现,我觉得 dom 不会重新呈现整个页面(我可能在这里错了,但尝试了很长时间并且没有任何效果)。
我尝试渲染的 HTML(这是作为 Post 请求出现的,这就是为什么我觉得不会发生重新渲染,因为当使用文档模型创建元素时它不是反应组件):
<style>
</style>
<div id="fig_el1692823804362488404764011855"></div>
<script>
function mpld3_load_lib(url, callback){
var s = document.createElement('script');
s.src = url;
s.async = true;
s.onreadystatechange = s.onload = callback;
s.onerror = function(){console.warn("failed to load library " + url);};
document.getElementsByTagName("head")[0].appendChild(s);
}
if(typeof(mpld3) !== "undefined" && mpld3._mpld3IsLoaded){
// already loaded: just create the figure
!function(mpld3){
mpld3.draw_figure("fig_el1692823804362488404764011855", {"width": 640.0, "height": 480.0, "axes": [{"bbox": [0.125,
0.10999999999999999, 0.775, 0.77], "xlim": [-0.2, 4.2], "ylim": [0.8, 5.2], "xdomain": [-0.2, 4.2], "ydomain": [0.8, 5.2],
"xscale": "linear", "yscale": "linear", "axes": [{"position": "bottom", "nticks": 11, "tickvalues": null, "tickformat": null, "scale": "linear", "fontsize": 10.0, "grid": {"gridOn": false}, "visible": true}, {"position": "left", "nticks": 11, "tickvalues": null, "tickformat": null, "scale": "linear", "fontsize": 10.0, "grid": {"gridOn": false}, "visible": true}], "axesbg": "#FFFFFF", "axesbgalpha": null, "zoomable": true, "id": "el169282380436246664", "lines": [{"data": "data01", "xindex": 0, "yindex": 1, "coordinates": "data", "id": "el169282380435913992", "color": "#1F77B4", "linewidth": 1.5, "dasharray":
"none", "alpha": 1, "zorder": 2, "drawstyle": "default"}], "paths": [], "markers": [], "texts": [], "collections": [], "images": [], "sharex": [], "sharey": []}], "data": {"data01": [[0.0, 3.0], [1.0, 1.0], [2.0, 4.0], [3.0, 1.0], [4.0, 5.0]]}, "id": "el169282380436248840", "plugins": [{"type": "reset"}, {"type": "zoom", "button": true, "enabled": false}, {"type": "boxzoom", "button": true, "enabled": false}]});
}(mpld3);
}else if(typeof define === "function" && define.amd){
// require.js is available: use it to load d3/mpld3
require.config({paths: {d3: "https://mpld3.github.io/js/d3.v3.min"}});
require(["d3"], function(d3){
window.d3 = d3;
mpld3_load_lib("https://mpld3.github.io/js/mpld3.v0.3.js", function(){
mpld3.draw_figure("fig_el1692823804362488404764011855", {"width": 640.0, "height": 480.0, "axes": [{"bbox": [0.125, 0.10999999999999999, 0.775, 0.77], "xlim": [-0.2, 4.2], "ylim": [0.8, 5.2], "xdomain": [-0.2, 4.2], "ydomain": [0.8, 5.2], "xscale": "linear", "yscale": "linear", "axes": [{"position": "bottom", "nticks": 11, "tickvalues": null, "tickformat": null, "scale": "linear", "fontsize": 10.0, "grid": {"gridOn": false}, "visible": true}, {"position": "left", "nticks": 11, "tickvalues": null, "tickformat": null, "scale": "linear", "fontsize": 10.0, "grid": {"gridOn": false}, "visible": true}], "axesbg": "#FFFFFF", "axesbgalpha": null, "zoomable": true, "id": "el169282380436246664", "lines": [{"data": "data01", "xindex": 0, "yindex": 1, "coordinates": "data", "id": "el169282380435913992", "color": "#1F77B4", "linewidth": 1.5, "dasharray": "none", "alpha": 1, "zorder": 2, "drawstyle": "default"}], "paths": [], "markers": [], "texts": [], "collections": [], "images": [], "sharex": [], "sharey": []}], "data": {"data01": [[0.0, 3.0], [1.0, 1.0], [2.0, 4.0], [3.0, 1.0], [4.0, 5.0]]}, "id": "el169282380436248840", "plugins": [{"type": "reset"}, {"type": "zoom", "button": true, "enabled": false}, {"type":
"boxzoom", "button": true, "enabled": false}]});
});
});
}else{
// require.js not available: dynamically load d3 & mpld3
mpld3_load_lib("https://mpld3.github.io/js/d3.v3.min.js", function(){
mpld3_load_lib("https://mpld3.github.io/js/mpld3.v0.3.js", function(){
mpld3.draw_figure("fig_el1692823804362488404764011855", {"width": 640.0, "height": 480.0, "axes": [{"bbox": [0.125, 0.10999999999999999, 0.775, 0.77], "xlim": [-0.2, 4.2], "ylim": [0.8, 5.2], "xdomain": [-0.2, 4.2], "ydomain": [0.8, 5.2], "xscale": "linear", "yscale": "linear", "axes": [{"position": "bottom", "nticks": 11, "tickvalues": null, "tickformat": null, "scale": "linear", "fontsize": 10.0, "grid": {"gridOn": false}, "visible": true}, {"position": "left", "nticks": 11, "tickvalues": null, "tickformat": null, "scale": "linear", "fontsize": 10.0, "grid": {"gridOn": false}, "visible": true}], "axesbg": "#FFFFFF", "axesbgalpha": null, "zoomable": true, "id": "el169282380436246664", "lines": [{"data": "data01", "xindex": 0, "yindex": 1, "coordinates": "data", "id": "el169282380435913992", "color": "#1F77B4", "linewidth": 1.5, "dasharray": "none", "alpha": 1, "zorder": 2, "drawstyle": "default"}], "paths": [], "markers": [], "texts": [], "collections": [], "images": [], "sharex": [], "sharey": []}], "data": {"data01": [[0.0, 3.0], [1.0, 1.0], [2.0, 4.0], [3.0, 1.0], [4.0, 5.0]]}, "id": "el169282380436248840", "plugins": [{"type": "reset"}, {"type": "zoom", "button": true, "enabled": false}, {"type": "boxzoom", "button": true, "enabled": false}]});
})
});
}
</script>
我正在尝试的方法是因为我找不到足够好的库来准确地将我的 html 转换为 jsx(如果有这样的 React 库可以转换代码,如果有人可以转换上面的 html 并检查那会很棒):
var App = (props) => {
const [dataFrameComponent, setDataFrameComponent] = React.useState("");
useEffect(() => {
const element = document.getElementById("dataframe");
if(typeof(element) != 'undefined' && element!= null){
document.getElementById('dataframe').style.width = "500"
document.getElementById('dataframe').style.height = "500"
document.getElementById('dataframe').innerHTML = dataFrameComponent
}
else{
const script = document.createElement("div");
script.id = 'dataframe'
script.style.height = '200'
script.style.width = '200'
const root = document.getElementById('root')
root.appendChild(script);
}
})
const [number, setNumber] = React.useState(0);
const handleSubmit=(event) => {
event.preventDefault();
let formData = new FormData(); //formdata object
formData.append('number', number);
console.log(formData);
console.log(formData.keys())
fetch('http://127.0.0.1:5000/dataframe',{
method: 'POST',
body: formData
})
.then((data)=> data.text()).then((data) => setDataFrameComponent(data))
}
return (
<div className="App">
<header className="App-header">
<form onSubmit={handleSubmit}>
<label>Enter the number of Elements: </label>
<input type="text" name= "number" onChange={(event) => {setNumber(event.target.value)} } />
<input type="submit" value="Submit" />
</form>
</header>
</div>
);
}
export default App;
我想动态渲染的图形是这样的。https://codepen.io/sherwinfarrell/pen/vYOPBVo
这与我在此处包含的 html 代码相同。
解决方案
PS谨慎使用这两种方法。
1-您可以使用 createContextualFragment 在没有库的情况下执行此操作:
import React from 'react';
const html = `
your html here
`;
class App extends React.Component {
componentDidMount() {
const wrapper = document.querySelector('#d3_code');
const range = document.createRange();
range.setStart(wrapper, 0);
wrapper.appendChild(
range.createContextualFragment(html)
);
}
render() {
return (
<div>React Snippet</div>
)
}
}
export default App;
2- 第二种方法是使用 dangerously-set-html-content 库:
import React from 'react';
import InnerHTML from 'dangerously-set-html-content'
const html = `
your html here
`;
class App extends React.Component {
render() {
return (
<div>
<InnerHTML html={html} />
</div>
)
}
}
export default App;
推荐阅读
- python - 如何按文件扩展名的有序列表对 python 文件列表进行排序
- c++ - 如何以准确的方式找到标记的中心?
- javascript - 检查 id jquery 对象是否为空
- php - 将字符串拆分为多个部分 Laravel
- html - 基于前一个元素中的内容的文本的XPath?
- sql - 创建 CTXCAT 索引时如何定义表空间
- c# - 在 Catch 子句中使用 GoTo 重申 Try 语句?
- sql - sql oracle goup by 日期可能为空值
- django - 清理后的数据仅显示最后一个表单集数据
- datatables - 如何从 json 字符串中提取记录以显示在 Jquery Datatable 中?