我正在尝试在React中实现Infinite Scroll,并且我希望在一个容器结束而另一个容器启动后立即更改URL。 如果我向上滚动并查看以前的容器,URL应该改回来。
我做了什么:我已经成功实现了无限滚动。并试图根据容器的高度和页面上的window.scrollY值来查找容器的位置。
由于这个原因,我需要更新State中的值,并且我已经在render中使用window.onscroll来检查条件并相应地更新状态。
问题是什么:我遇到的问题是我没有得到期望的结果,并且我知道我不应该在render()中使用setState。但是,如果必须根据render()内window.onscroll中的条件完成此操作,我还能在哪里更新状态。
InfiniteScrollingComponent.js
state = {
height: [],
containerThatIsBeingRenderedArr: [],
elementIndex: 0,
upperBound: 0,
lowerBound: null
};
componentDidUpdate = (prevProps, prevState) => {
let urlArr = [], height = [], containerThatIsBeingRenderedArr = [];
for (let index in this.props.items) {
containerThatIsBeingRenderedArr[index] = document.getElementById(
`${this.props.items[index].slug}`
);
height[index] = containerThatIsBeingRenderedArr[index].offsetHeight;
}
if (prevState.containerThatIsBeingRenderedArr.length === containerThatIsBeingRenderedArr.length) return;
if (containerThatIsBeingRenderedArr.length && height.length) {
this.setState(
{
height: height,
containerThatIsBeingRenderedArr: containerThatIsBeingRenderedArr
}
);
}
};
然后在render()方法中,我有:
window.onscroll = () => {
this.changeURL();
}
changeURL方法如下:
changeURL = () => {
const { elementIndex, height, upperBound, lowerBound } = this.state;
let LB = lowerBound === null ? height[0] : lowerBound;
if (window.scrollY > upperBound && window.scrollY < LB) {
return;
}
if (window.scrollY > LB) {
this.setState(prevState => {
return {
upperBound: prevState.lowerBound,
lowerBound: LB + prevState.height[prevState.elementIndex + 1],
elementIndex: prevState.elementIndex + 1
};
});
}
if (window.scrollY < upperBound) {
this.setState(prevState => {
return {
lowerBound: prevState.upperBound,
upperBound:
prevState.upperBound - prevState.height[prevState.elementIndex - 1],
elementIndex: prevState.elementIndex - 1
};
});
}
};