简体   繁体   English

在反应中操作 DOM

[英]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 using innerHTML 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 out dangerouslySetInnerHTML 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 )。

you can look into using ReactRef instead of having to manipulate the DOM directly, it's easier, safer and more best practice.你可以考虑使用 ReactRef 而不是直接操作 DOM,它更容易、更安全和更佳实践。

check here在这里检查

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

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