Можно ли напрямую изменять атрибуты контролируемых React элементов DOM?

Я хотел бы использовать headroom.js с React. Документы Headroom.js говорят:

По своей сути, headroom.js просто добавляет и удаляет классы CSS из элемента в ответ на событие прокрутки.

Было бы хорошо использовать его напрямую с элементами, контролируемыми React? Я знаю, что React терпит неудачу, когда структура DOM видоизменяется, но изменение только атрибутов должно быть хорошо. Это действительно так? Не могли бы вы показать мне место в официальной документации, в котором говорится, что это рекомендуется или нет?

Примечание: я знаю о реакционном запасе, но вместо этого я бы хотел использовать оригинальный headroom.js.

РЕДАКТИРОВАТЬ: Я только что попробовал, и это похоже на работу. Я до сих пор не знаю, будет ли это хорошей идеей в долгосрочной перспективе.

1 ответ

Решение

Если 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

Мы начнем с компонента, который имеет классы blue а также bold исходя из его состояния. Через секунду мы добавляем grayBg класс без использования React. Еще через секунду компонент устанавливает свое состояние, чтобы компонент имел классы blue, bold, а также bigи grayBg класс потерян.

Поскольку стратегия согласования DOM - это черный ящик, трудно сказать: "Хорошо, мой вариант использования будет работать до тех пор, пока React не определит какие-либо классы". Например, React может решить, что лучше использовать innerHTML применять большой список изменений, а не устанавливать атрибуты индивидуально.

В общем, если вам нужно выполнять ручную DOM-обработку компонента React, лучшая стратегия заключается в том, чтобы обернуть ручную операцию или плагин в свой собственный компонент, который он может контролировать на 100%. Посмотрите этот пост на Wrapping DOM Libs для одного такого примера.

Другие вопросы по тегам