const fetchScrollData = () => {
// Here we set that we are not able to do scrolling fetching
setIsLoadingScrollData(true);
// Apply here some pagination calculation
searchData()
.then((tempData) => {
// Here i am saving the id of the first message
// I had before scrolling
setShouldScrollToId(data[0].id);
const newData = tempData.concat(data);
setData(newData);
// Apply here some logic, depending if you have finished or not
setHasMoreData(true);
})
.then(() => {
setTimeout(() => {
// Change the timeout accordingly
// hack for setting the isloading to false when everything is done
setIsLoadingScrollData(false);
}, 1500);
});
};
子组件
type PropsType = {
fetchScrollData: () => void;
hasMoreData: boolean;
data: string[];
isLoadingScrollData: boolean;
shouldScrollToId: string;
};
const ChildComponent: FC<PropsType> = (props: PropsType) => {
useEffect(() => {
if (props.shouldScrollToId !== '') {
const element = document.getElementById(props.shouldScrollToId);
if (element) {
element.scrollIntoView({ behavior: 'smooth' });
}
}
});
....
return (
<div
className="message-list overflow-scroll"
id="scrollableDiv"
style={{
display: 'flex',
flexDirection: 'column-reverse'
}}>
<InfiniteScroll
dataLength={props.data.length}
hasMore={props.hasMoreData && !props.isLoadingScrollData}
inverse={true}
next={props.fetchScrollData}
scrollableTarget="scrollableDiv"
style={{ display: 'flex', flexDirection: 'column-reverse', perspective: '1px' }}
loader={<></>}>
<div>
{props.data.map((d, index) => {
// Here i am setting the id which the useEffect will use to do the scroll
<div key={index} id={d.id} >div - #{message}</div>;
})}
</div>
{props.isLoadingScrollData ? <Spinner></Spinner> : null}
</InfiniteScroll>
</div>
2条答案
按热度按时间cotxawn71#
如果您有所加入新元素的指涉,可以使用element.scrollIntoView()来确定呈现后它是可见的。
https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView
但是:在聊天室里,这可能并不总是正确的做法,因为用户可能会向上滚动来复制/粘贴一些东西,而丢失位置会很烦人。所以在通过JS滚动之前,请检查聊天是否已经在底部。
你可以看看twitch-chat是如何工作的,以获得一个很好的例子。如果有新的聊天消息,用户会得到一个信息。
mspsb9vt2#
此解决方案适用于库https://github.com/ankeetmaini/react-infinite-scroll-component
我使用的结构是基于传递给子组件的道具。父组件正在获取和控制状态。
父组件:
子组件
我的加载器有一些问题,所以我决定不使用它。相反,我创建了我自己的
Spinner
组件,并根据显示是否仍在从滚动中获取数据的属性使其出现或消失。