嗨,这更像是一个问题,我想就componentDidUpdate
DOM 操作展开讨论。
我正在创建一个 React 插件。 它必须做一些 DOM 计算,因为 CSS 不够强大,无法涵盖这个插件需要做的一切。 问题是我需要根据由同一组件呈现的其他一些 DOM 元素的 getBoundingClientRect() 的返回值来调整一些 CSS 属性。
所以从技术上讲,我们有 3 个选择:
1) 在componentDidUpdate
计算getBoundingClientRect
并用计算值调用setState
。 我害怕在某些情况下可能发生无限循环,所以我不会选择这个。
2) 像在 1) 中那样做,并用shouldComponentUpdate
玩一下,但这看起来非常复杂且不可读。 会弹出许多取决于特定用例的问题。
3) 从 componentDidUpdate 更新 DOM。 这是我决定采用的解决方案,它有效,简单,稳定并且按预期工作。 但是我觉得我处于边缘,所以我想仔细检查一下这是一种可以做事的方式。 可以在componentDidUpdate
操作 DOM 吗? 每次完成render
都会调用它,我可以放弃我的更改,因为接下来的render
我将再次修改 DOM。
这是代码的一部分
componentDidMount() {
this.recalculateIndent();
}
componentDidUpdate() {
this.recalculateIndent();
}
recalculateIndent() {
// calculate indent based on getBoundingClientRect of some DOM reference
this.textareaRef.style.textIndent = `${indent}px`;
}
render() {
return (
...
<textarea ref={ref => this.textareaRef = ref}/>
...
);
}
每种解决方案(组件生命周期方法)都适合具体情况,但DOM操作是错误的。 使用状态并重新渲染组件。 我上一个用例“固定表头+表体虚拟滚动”的示例,我希望这能帮助您理解正确的流程。
@jvorcak使用componentDidUpdate
是在渲染后手动操作 DOM 的正确位置。 根据文档:
以此为契机,在组件更新后对 DOM 进行操作。
此外,我们尝试仅将问题跟踪器用于功能请求和错误报告。 使用问题应该指向其他地方,比如Discussion.reactjs.org或 StackOverflow。 谢谢!
如果您想在更改另一个组件后更新一个组件怎么办?
最有用的评论
@jvorcak使用
componentDidUpdate
是在渲染后手动操作 DOM 的正确位置。 根据文档:此外,我们尝试仅将问题跟踪器用于功能请求和错误报告。 使用问题应该指向其他地方,比如Discussion.reactjs.org或 StackOverflow。 谢谢!