简体   繁体   English

是否可以直接改变React控制的DOM元素的属性?

[英]Is it fine to mutate attributes of React-controlled DOM elements directly?

I'd like to use headroom.js with React. 我想将headroom.js与React一起使用。 Headroom.js docs say: Headroom.js文档说:

At it's most basic headroom.js simply adds and removes CSS classes from an element in response to a scroll event. 在它最基本的headroom.js只是添加和删除元素中的CSS类以响应滚动事件。

Would it be fine to use it directly with elements controlled by React? 将它直接用于React控制的元素是否可以? I know that React fails badly when the DOM structure is mutated, but modifying just attributes should be fine. 我知道当DOM结构发生变异时,React会失败 ,但修改属性应该没问题。 Is this really so? 这真的是这样吗? Could you show me some place in official documentation saying that it's recommended or not? 你能否在官方文件中告诉我一些地方,建议与否?

Side note: I know about react-headroom , but I'd like to use the original headroom.js instead. 旁注:我知道反应空间 ,但我想使用原始的headroom.js。

EDIT: I just tried it, and it seems to work. 编辑:我刚尝试过,它似乎工作。 I still don't know if it will be a good idea on the long run. 从长远来看,我仍然不知道这是不是一个好主意。

If React tries to reconcile any of the attributes you change, things will break. 如果React试图协调你改变的任何属性,事情就会破裂。 Here's an example: 这是一个例子:

class Application extends React.Component {
  constructor() {
    super();
    this.state = {
      classes: ["blue", "bold"]
    }
  }

  componentDidMount() {
    setTimeout(() => {
      console.log("modifying state");
      this.setState({
        classes: this.state.classes.concat(["big"])
      });
    }, 2000)
  }

  render() {
    return (
      <div id="test" className={this.state.classes.join(" ")}>Hello!</div>
    )
  }
}

ReactDOM.render(<Application />, document.getElementById("app"), () => {
  setTimeout(() => {
    console.log("Adding a class manually");
    const el = document.getElementById("test");
    if (el.classList)
      el.classList.add("grayBg");
    else
      el.className += ' grayBg';
  }, 1000)
});

And here's the demo: https://jsbin.com/fadubo/edit?js,output 这是演示: https//jsbin.com/fadubo/edit?js,output

We start off with a component that has the classes blue and bold based on its state. 我们从一个基于其状态的bluebold类的组件开始。 After a second, we add the grayBg class without using React. 一秒钟后,我们添加grayBg而不使用React。 After another second, the component sets its state so that the component has the classes blue , bold , and big , and the grayBg class is lost. 在另一秒之后,组件设置其状态,以便组件具有blueboldbig类,并且grayBg类丢失。

Since the DOM reconciliation strategy is a black box, it's difficult to say, "Okay, my use case will work as long as React doesn't define any classes." 由于DOM协调策略是一个黑盒子,很难说,“好吧,只要React没有定义任何类,我的用例就会起作用。” For example, React might decide it's better to use innerHTML to apply a large list of changes rather than setting attributes individually. 例如,React可能会决定使用innerHTML来应用大量更改而不是单独设置属性。

In general, if you need to do manual DOM manipulation of a React component, the best strategy is to wrap the manual operation or plugin in its own component that it can 100% control. 通常,如果您需要对React组件进行手动DOM操作,最好的策略是将手动操作或插件包装在它可以100%控制的自己的组件中。 See this post on Wrapping DOM Libs for one such example. 有关此类示例,请参阅有关包装DOM Libs的这篇文章

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

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