在设置元素的innerHTML和在元素上设置dangerlysetinnerhtml属性之间有什么“幕后”区别吗?假设为了简单起见,我正在正确地消毒。
例子:
var test = React.createClass({
render: function(){
return (
<div contentEditable='true' dangerouslySetInnerHTML={{ __html: "Hello" }}></div>
);
}
});
vs
var test = React.createClass({
componentDidUpdate: function(prevProp, prevState){
this.refs.test.innerHTML = "Hello";
},
render: function(){
return (
<div contentEditable='true' ref='test'></div>
);
}
});
我正在做的事情比上面的例子更复杂一些,但总体思想是相同的
是的,有区别!
使用innerHTML与使用dangerlysetinnerhtml的直接效果是相同的——DOM节点将使用注入的HTML进行更新。
然而,在幕后,当你使用dangerlysetinnerhtml时,它会让React知道该组件中的HTML不是它关心的东西。
由于React使用虚拟DOM,当它与实际DOM进行比较时,它可以直接绕过检查该节点的子节点,因为它知道HTML来自另一个来源。这是性能上的提升。
更重要的是,如果只是使用innerHTML, React无法知道DOM节点已被修改。下一次调用渲染函数时,React将用它认为DOM节点的正确状态覆盖手动注入的内容。
你的解决方案使用componentDidUpdate总是确保内容是同步的,我相信会工作,但在每次渲染期间可能会有一个闪光。
根据dangerous Set innerHTML,
Improper use of the innerHTML can open you up to a cross-site
scripting (XSS)
attack. Sanitizing user input for display is notoriously error-prone,
and failure to properly sanitize is one of the leading causes of web
vulnerabilities on the internet.
Our design philosophy is that it should be "easy" to make things safe,
and developers should explicitly state their intent when performing
“unsafe” operations. The prop name dangerouslySetInnerHTML is
intentionally chosen to be frightening, and the prop value (an object
instead of a string) can be used to indicate sanitized data.
After fully understanding the security ramifications and properly
sanitizing the data, create a new object containing only the key
__html and your sanitized data as the value. Here is an example
using the JSX syntax:
function createMarkup() {
return {
__html: 'First · Second' };
};
<div dangerouslySetInnerHTML={createMarkup()} />
使用下面的链接阅读更多信息:
文档:React DOM Elements - dangerlysetinnerhtml。