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

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

我想将 headroom.js 与 React 一起使用。 Headroom.js 文档说:

At it's most basic headroom.js simply adds and removes CSS classes from an element in response to a scroll event.

直接用React控制的元素可以吗?我知道 React fails badly 当 DOM 结构发生变化时,但只修改属性应该没问题。真的是这样吗?你能告诉我官方文档中的一些地方说推荐或不推荐吗?

旁注:我知道 react-headroom,但我想改用原来的 headroom.js。

编辑:我刚刚试过了,它似乎有效。我仍然不知道从长远来看这是否是个好主意 运行。

如果 React 试图协调您更改的任何属性,事情就会崩溃。这是一个例子:

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

这是演示:https://jsbin.com/fadubo/edit?js,output

我们从一个组件开始,该组件根据其状态具有 classes bluebold。一秒钟后,我们使用 React 添加 grayBg class without。又过了一秒钟,组件设置其状态,使组件具有 classes blueboldbig,以及 grayBg class丢失了。

由于 DOM 协调策略是一个黑盒,所以很难说,"Okay, my use case will work as long as React doesn't define any classes." 例如,React 可能决定使用 innerHTML 来应用一个大列表更好更改而不是单独设置属性。

一般来说,如果你需要对 React 组件进行手动 DOM 操作,最好的策略是将手动操作或插件包装在它自己的组件中,它可以 100% 控制。参见 this post on Wrapping DOM Libs 中的一个示例。