简体   繁体   English

React.js:设置 innerHTML 与 dangerouslySetInnerHTML

[英]React.js: Set innerHTML vs dangerouslySetInnerHTML

Is there any "behind the scenes" difference from setting an element's innerHTML vs setting the dangerouslySetInnerHTML property on an element?设置元素的 innerHTML 与设置元素的 dangerouslySetInnerHTML 属性有什么“幕后”区别吗? Assume I'm properly sanitizing things for the sake of simplicity.假设为了简单起见,我正在对事物进行适当的消毒。

Example:例子:

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>
    );
  }
});

I'm doing something a bit more complicated than the above example, but the overall idea is the same我正在做一些比上面的例子更复杂的事情,但总体思路是一样的

Yes there is a difference!是的,有区别!

The immediate effect of using innerHTML versus dangerouslySetInnerHTML is identical -- the DOM node will update with the injected HTML.使用innerHTML与使用dangerouslySetInnerHTML的直接效果是相同的——DOM 节点将使用注入的HTML 进行更新。

However , behind the scenes when you use dangerouslySetInnerHTML it lets React know that the HTML inside of that component is not something it cares about.然而,在幕后,当您使用dangerouslySetInnerHTML SetInnerHTML 时,它让 React 知道该组件内部的 HTML 不是它关心的东西。

Because React uses a virtual DOM, when it goes to compare the diff against the actual DOM, it can straight up bypass checking the children of that node because it knows the HTML is coming from another source .因为 React 使用虚拟 DOM,当它比较 diff 与实际 DOM 时,它可以直接绕过检查该节点的子节点,因为它知道 HTML 来自另一个源 So there's performance gains.所以有性能提升。

More importantly , if you simply use innerHTML , React has no way to know the DOM node has been modified.更重要的是,如果你只是简单地使用innerHTML ,React 没有办法知道 DOM 节点被修改了。 The next time the render function is called, React will overwrite the content that was manually injected with what it thinks the correct state of that DOM node should be.下一次调用render函数时, React 将覆盖手动注入的内容,它认为该 DOM 节点的正确状态应该是什么。

Your solution to use componentDidUpdate to always ensure the content is in sync I believe would work but there might be a flash during each render.您使用componentDidUpdate始终确保内容同步的解决方案我相信会奏效,但在每次渲染期间可能会有闪光。

According to Dangerously Set innerHTML ,根据Dangerously Set innerHTML

Improper use of the innerHTML can open you up to a cross-site scripting (XSS) attack.innerHTML不当使用会使您innerHTML跨站点脚本(XSS)攻击。 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.众所周知,清理用于显示的用户输入容易出错,而未能正确清理是导致 Internet 上 Web 漏洞的主要原因之一。

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.道具名称dangerouslySetInnerHTML被故意选择为令人恐惧,道具值(一个对象而不是字符串)可用于指示已清理的数据。

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.在充分了解安全后果并正确清理数据后,创建一个仅包含密钥__html和清理数据作为值的新对象。 Here is an example using the JSX syntax:下面是一个使用 JSX 语法的例子:

function createMarkup() {
    return {
       __html: 'First &middot; Second'    };
 }; 

<div dangerouslySetInnerHTML={createMarkup()} /> 

Read more about it using below link:使用以下链接阅读更多信息:

documentation : React DOM Elements - dangerouslySetInnerHTML .文档React DOM Elements-dangerouslySetInnerHTML

可以直接绑定dom

<div dangerouslySetInnerHTML={{__html: '<p>First &middot; Second</p>'}}></div>

Based on ( dangerouslySetInnerHTML ).基于( 危险的SetInnerHTML )。

It's a prop that does exactly what you want.这是一个完全符合您要求的道具。 However they name it to convey that it should be use with caution然而,他们命名它是为了表达应该谨慎使用它

Yes there is a difference b/w the two: dangerouslySetInnerHTML : React diffing algorithm ( https://reactjs.org/docs/reconciliation.html ) is designed to ignore the HTML nodes modified under this attribute thereby slightly improving the performance .是的,两者之间存在差异:危险的SetInnerHTML:React diffing算法( https://reactjs.org/docs/reconciliation.html )旨在忽略在此属性下修改的HTML节点,从而略微提高性能。 If we use innerHTML, React has no way to know the DOM is modified.如果我们使用innerHTML,React 无法知道DOM 被修改了。 The next time the render happens , React will overwrite the content that was manually injected with what it thinks the correct state of that DOM node should be.下一次渲染发生时,React 将覆盖手动注入的内容,它认为该 DOM 节点的正确状态应该是什么。 That's where componentDidUpdate comes to rescue !!这就是 componentDidUpdate 来拯救的地方!

<div style={{whiteSpace: 'pre-wrap'}}>{data}</div>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM