我只想在视口(viewport)中的组件中执行某些操作。它几乎可以工作,但我有一个无法解决的问题。
class Hello extends React.Component {
componentDidMount() {
console.log(this.isInViewPort()) // false for second element - last in viewport
if (this.isInViewPort()) {
console.log("I'm in viewport!");
}
window.addEventListener('scroll', this.handleScroll);
}
componentWillUnmount() {
window.removeEventListener('scroll', this.handleScroll);
}
isInViewPort = () => {
const element = this.refs[this.props.id];
const rect = element.getBoundingClientRect();
const windowHeight = window.innerHeight || document.documentElement.clientHeight;
const result = rect.top <= windowHeight && rect.top + rect.height >= 0;
return result;
}
handleScroll = () => {
if (this.isInViewPort()) {
console.log("I'm in viewport!");
}
}
render() {
return (
<div className="example" ref={this.props.id} onClick={this.handleScroll} /> // onClick added for tests
);
}
}
class App extends React.Component {
render() {
return (
<Hello id={1} />
<Hello id={2} />
<Hello id={3} />
);
}
}
.example {
width: 400px;
height: 400px;
background-color: red;
}
当我加载页面时,两个元素位于视口(viewport)中。第一个 - 100% 在视口(viewport)中,第二个 - 也许 15-20% 在视口(viewport)中。
对于这个示例,我只有一个 console.log,因此 this.isInViewPort() 仅对于第一个元素为 true。这是错误的,因为其中两个是可见的。
当我触摸事件滚动时,组件立即可见方法并生成控制台日志。当我不触摸滚动条,而是单击第二个组件(这是为了测试而添加的)时,方法返回 true 并且我得到 console.log。
我想制作当每个可见元素通过方法返回 true 时的情况。
当我这样做时它起作用了:
componentDidMount() {
setTimeout(() => {
if (this.isInViewPort()) {
console.log("I'm in viewport!");
}, 0);
}
但是对于 100% 来说这不是一个好的解决方案。当我将这段代码重构为 componentDidUpdate() 后,它也不起作用。
这是有反应生命周期的东西吗?我没有做任何巫术状态的事情,这就是为什么我无法理解。
最佳答案
我相信您的问题可能与您测试项目的位置以及交付文件的方式等有关。 我创建了一个 fiddle 来测试它:
.example {
width: 400px;
height: 90vh;
background-color: red;
border: 1px solid black;
}
https://jsfiddle.net/284Ldvkc/
我只将高度从 400px 更改为 90vh,因此我要确保始终 1 在 View 中,2 在 View 中,比例为 10%。
关于javascript - react : method return wrong value on componentDidMount,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55709969/