【发布时间】:2019-05-01 15:57:41
【问题描述】:
我想在 componentDidMount() 方法中操作 ReactJS 中的 DOM。我的问题是,此时 DOM 没有以某种方式完全呈现,我需要一个 setTimeout 函数,我宁愿省略它。
当我在 componentDidMount() 中 console.log 渲染元素的 scrollHeight 时,它给了我一个不同的数字,就像我等待 100 毫秒时一样。
我想要实现的是向下滚动到此处描述的元素的末尾How to scroll to bottom in react?
该组件是一个模态窗口,它呈现另一个组件的{this.props.children}。 modal-window 使用visibility: hidden 和opacity: 0 渲染到DOM 中,并且当它第一次出现在页面上时,它具有窗口的高度。通过单击一个按钮,它会显示出来,并且在我等待几毫秒之前仍然具有窗口的高度。
我猜,当需要 setTimeout 时,我在这里做错了,但我没有发现是什么。
我还尝试在 componentDidUpdate() 方法中更改 DOM,结果相同。
我在modal-window组件中写了这段代码:
componentDidMount() {
console.log(document.querySelector('.myModal').scrollHeight);
setTimeout(function() {
console.log(document.querySelector('.myModal').scrollHeight);
}, 100);
}
第一个 console.log 给我例如 497,第二个类似 952。
更新
我有一个模态窗口组件,例如为我的收件箱线程呈现这样的孩子:
<Modal>
<InboxThread />
</Modal>
问题是,我需要等到 modal-window 组件在 Modal.js 中像这样呈现它的子组件:
render() {
return (
<React.Fragment>
{this.props.children}
</React.Fragment>
);
}
所以我最后的解决方案是从父组件的 props 中交出一个方法,我在其中调用 modal 来检查 Modal.js 中是否有 componentDidUpdate()。
我的代码在父组件中现在看起来像这样:
...
export default class InboxThreadList extends React.Component {
constructor(props) {
super(props);
this.scrollToModalBottom = this.scrollToModalBottom.bind(this);
}
render() {
return (
<React.Fragment>
...
<Modal onRender={this.scrollToModalBottom}>
<InboxThread/>
</Modal>
</React.Fragment>
)
}
scrollToModalBottom() {
const myModalObject = document.querySelector('.myModal');
myModalObject.scrollTop = myModalObject.scrollHeight;
}
}
在 Modal.js 中:
...
export default class Modal extends React.Component {
...
componentDidUpdate() {
if ('onRender' in this.props) {
this.props.onRender();
}
}
render() {
return (
<div className={'myModal'}>
{this.props.children}
</div>
);
}
我知道!我仍然应该使用 refs 而不是 document.querySelector,我将按照此处React - Passing ref from dumb component(child) to smart component(parent) 的描述进行操作。
【问题讨论】:
-
componentDidMount() 的全部意义在于确保 DOM 已加载,因此您绝对不想使用 setTimeout。看起来您正在使用父母 componentDidMount() 而不是 Modals?此外,您不应该直接使用 ref 访问 DOM
标签: javascript css reactjs