[英]Manipulating DOM in react
I am aware that manipulating DOM directly in react is not a considered a good practice.我知道在 React 中直接操作 DOM 并不是一个好的做法。 As react reconciliation engine will hit performance when comparing virtual DOM and real DOM由于在比较虚拟 DOM 和真实 DOM 时,react 协调引擎会影响性能
But what if I do something like this?但是如果我做这样的事情呢?
Scenario shown only to explain question.显示的场景仅用于解释问题。 No answer is needed for this specific scenario but to this practice as general with the downsides对于这种特定情况不需要答案,但这种做法一般都有缺点
Scenario: 1场景:1
state = {
innerHTML : ""
}
document.getElementById("test").innerHTML = this.state.innerHTML
handleChange(){
//...handles change in state
}
Scenario: 2场景:2
state = {
color:"red"
}
document.getElementById("test").style.color = this.state.color
handleChange(color){
this.setState({color})
}
In such as scenario react is aware that it needs to re-render as I am changing the state there-by maintaining the consistency of both Virtual and Real DOM .在这种情况下,react 意识到它需要重新渲染,因为我正在更改状态,从而保持 Virtual DOM 和 Real DOM 的一致性。
So in all such situations where I can use state to maintain consistency and make changes to real DOM is it still a bad idea to make changes to real DOM in this way?因此,在所有这些我可以使用状态来保持一致性并对真实 DOM 进行更改的情况下,以这种方式对真实 DOM 进行更改仍然是一个坏主意吗?
In that case, rather than setting innerHTML
directly, you should be using dangerouslySetInnerHTML
:在这种情况下,与其直接设置innerHTML
,不如使用dangerouslySetInnerHTML
:
class Component extends React.Component {
state = {
innerHTML: '',
}
handleChange() {
this.setState({ innerHTML: '...' });
}
render() {
return <div dangerouslySetInnerHTML={ { __html: this.state.innerHTML } }></div>;
}
}
As stated in the docs:如文档中所述:
dangerouslySetInnerHTML 危险地SetInnerHTML
dangerouslySetInnerHTML
is React's replacement for usinginnerHTML
in the browser DOM.dangerouslySetInnerHTML
是 React 在浏览器 DOM 中使用innerHTML
的替代品。 In general, setting HTML from code is risky because it's easy to inadvertently expose your users to a cross-site scripting (XSS) attack.一般来说,从代码中设置 HTML 是有风险的,因为很容易在不经意间将用户暴露给跨站点脚本 (XSS) 攻击。 So, you can set HTML directly from React, but you have to type outdangerouslySetInnerHTML
and pass an object with a__html
key, to remind yourself that it's dangerous.所以,你可以直接从 React 设置 HTML,但是你必须输入dangerouslySetInnerHTML
的__html
并传递一个带有__html
键的对象,以提醒自己这是危险的。
Also, when using dangerouslySetInnerHTML
, React will ignore that part of the DOM when diffing the virtual DOM and the real DOM ( reconciliation ), so it will be more performant as it has less work to do.此外,当使用dangerouslySetInnerHTML
SetInnerHTML 时,React 将在区分虚拟 DOM 和真实 DOM(协调)时忽略 DOM 的那部分,因此它会更高效,因为它要做的工作更少。
And in any case, if you do:无论如何,如果你这样做:
document.getElementById('test').innerHTML = this.state.innerHTML;
At some point in your code, maybe in componentDidUpdate()
, and then render()
is called again (when you update the state or a parent component re-renders), your changes will be overwritten, so you would need to be constantly updating it, which might produce a small but noticeable flash and reduce performance, as each render will have to update the DOM 2 times (one from React and the other one from innerHTML
).在您的代码中的某个时刻,可能在componentDidUpdate()
,然后再次调用render()
(当您更新状态或父组件重新渲染时),您的更改将被覆盖,因此您需要不断更新它,这可能会产生一个小而明显的闪光并降低性能,因为每个渲染都必须更新 DOM 2 次(一次来自 React,另一次来自innerHTML
)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.