我想在 componentDidMount() 方法中操作 ReactJS 中的 DOM。我的问题是此时 DOM 没有以某种方式完全呈现,我需要一个 setTimeout 函数,我宁愿忽略它。
当我在 componentDidMount() 中对渲染元素的 scrollHeight 进行 console.log 时,它会给我一个不同的数字,因为当我等待比方说 100 毫秒时。
我想要实现的是向下滚动到此处描述的元素的末尾 How to scroll to bottom in react?
该组件是一个模态窗口,它呈现另一个组件的 {this.props.children}
。模态窗口以 visibility: hidden
和 opacity: 0
呈现到 DOM 中,当它首次出现在页面上时,它具有窗口的高度。通过单击一个按钮,它会显示出来并且仍然具有窗口的高度,直到我等待几毫秒。
我想,当需要 setTimeout 时,我在这里做错了什么,但我没有发现是什么。
我还尝试在 componentDidUpdate() 方法中更改 DOM,结果相同。
我在模态窗口组件中写了这段代码:
componentDidMount() {
console.log(document.querySelector('.myModal').scrollHeight);
setTimeout(function() {
console.log(document.querySelector('.myModal').scrollHeight);
}, 100);
}
第一个 console.log 给了我例如 497,第二个给了我 952 之类的东西。
更新
我有一个模态窗口组件,它为我的收件箱线程呈现一个像这样的 child :
<Modal>
<InboxThread />
</Modal>
问题是,我需要等到模态窗口组件在 Modal.js 中像这样呈现它的子组件:
render() {
return (
<React.Fragment>
{this.props.children}
</React.Fragment>
);
}
所以我最终的解决方案是在父组件的 props 中交出一个方法,我在父组件中调用模态来检查 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) .
最佳答案
如果您使用 ref
- 只要元素始终在 render() 中呈现 - 它保证在 componentDidMount 运行之前解析:
componentDidMount() {
// can use any refs here
}
componentDidUpdate() {
// can use any refs here
}
render() {
// as long as those refs were rendered!
return <div ref={/* ... */} />;
}
componentDidMount called BEFORE ref callback
所以在你的情况下,你可以像这样编码:
componentDidMount() {
console.log(this.mymodal.scrollHeight)
}
render() {
return <div className="mymodal" ref={ref => this.mymodal = ref} />
}
关于javascript - 在没有 setTimeout 的情况下在 componentDidMount() 中操作 DOM,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55939058/