Nic*_*ick 11 javascript reactjs dangerouslysetinnerhtml
我的 React 应用程序中有脚本,稍后会动态插入。脚本不加载。
\n在我的数据库中有一个名为 的字段content
,其中包含包含 html 和 javascript 的数据。有很多记录,每个记录可以包含该content
字段中的多个脚本。因此,在我的 React 应用程序中静态指定每个脚本 URL 并不是真正的选项。例如,记录的字段可能如下所示:
<p>Some text and html</p>\n<div id="xxx_hype_container">\n <script type="text/javascript" charset="utf-8" src="https://example.com/uploads/hype_generated_script.js?499892"></script>\n</div>\n<div style="display: none;" aria-hidden="true"> \n<div>Some text.</div> \nEtc\xe2\x80\xa6\n
Run Code Online (Sandbox Code Playgroud)\n我使用以下命令在我的 React 应用程序中调用此字段dangerouslySetInnerHTML
:
render() {\n return (\n <div data-page="clarifies">\n <div className="container">\n <div dangerouslySetInnerHTML={{ __html: post.content }} />\n ... some other data\n </div>\n </div>\n );\n}\n
Run Code Online (Sandbox Code Playgroud)\n它正确地从数据库加载数据并显示该数据的 html。但是,Javascript 不会被执行。我认为该脚本不起作用,因为它是稍后动态插入的。我怎样才能让这些脚本工作/运行?
\n这篇文章提出了动态插入脚本的解决方案,但我不认为我可以应用此解决方案,因为在我的情况下,脚本/代码是从数据库插入的(那么如何在nodeScriptReplace
代码上使用...?)。有什么建议可以让我的脚本发挥作用吗?
更新回应 @lissettdm 他们的答案:
\nconstructor(props) {\n this.ref = React.createRef();\n}\n\ncomponentDidUpdate(prevProps, prevState) {\n if (prevProps.postData !== this.props.postData) {\n this.setState({\n loading: false,\n post: this.props.postData.data,\n //etc\n });\n setTimeout(() => parseElements());\n\n console.log(this.props.postData.data.content);\n // returns html string like: `<div id="hype_container" style="margin: auto; etc.`\n const node = document.createRange().createContextualFragment(this.props.postData.data.content);\n console.log(JSON.stringify(this.ref));\n // returns {"current":null}\n console.log(node);\n // returns [object DocumentFragment]\n this.ref.current.appendChild(node);\n // produces error "Cannot read properties of null"\n }\n}\n\nrender() {\n const { history } = this.props;\n /etc.\n return (\n {loading ? (\n some code\n ) : (\n <div data-page="clarifies">\n <div className="container">\n <div ref={this.ref}></div>\n ... some other data\n </div>\n </div>\n );\n );\n}\n
Run Code Online (Sandbox Code Playgroud)\n该this.ref.current.appendChild(node);
行产生错误:
\n\n类型错误:无法读取 null 的属性(读取“appendChild”)
\n
如果您确定 HTML 字符串内容是安全的并且包含具有有效 HTML 的字符串,您可以使用Range.createContextualFragment()(执行脚本)
function App() {
const ref = useRef();
useEffect(() => {
/* convert your HTML string into DocumentFragment*/
const node = document.createRange().createContextualFragment(HTML);
ref.current.appendChild(node);
}, []);
return (
<div>
<h1>HTML String</h1>
<div>
<div ref={ref}></div>
</div>
</div>
);
}
Run Code Online (Sandbox Code Playgroud)
查看内容如何在 JavaScript 控制台工作示例script
上执行
如果您在类构造函数中使用class component
创建ref
,然后更新节点内容,我这样做componentDidMount
只是为了测试:
class App extends React.Component {
constructor(props) {
super(props);
this.ref = React.createRef();
}
componentDidMount() {
const node = document.createRange().createContextualFragment(HTML);
this.ref.current.appendChild(node);
}
render() {
return (
<div>
<h1>HTML String</h1>
<div>
<div ref={this.ref}></div>
</div>
</div>
);
}
}
Run Code Online (Sandbox Code Playgroud)
看这个工作示例
归档时间: |
|
查看次数: |
1622 次 |
最近记录: |