Можно ли напрямую изменять атрибуты контролируемых 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 для одного такого примера.