我试着用反应-无限-卷-分量做一个无限滚动
一切都像我想的那样完美,但问题是,每当我更改类型,或者按F5重新加载页面,或者滚动条总是在最底层,我确实尝试用window.scrollTo(0,0)修复它,但它仍然不能工作。
或者,不知怎么的,我把代码搞砸了,因为我努力地绕过它,但我认为我执行得不够好。
代码是非常的long,但是这里有一个简短的解释,说明我试图在其中做什么。
我收到了一个用useParams定义为useParams的段塞,例如action或adventure,然后我将它设置为一个状态genreAnime,然后检查它是否是相同的类型,它将对concat array进行无限加载,并在下一个加载时将页面增加到1,否则我将设置一个新的array,并将页面初始化为1,否则它将继续与以前的genre的旧数组合并。totalPage设置为91,每当它第二次呈现时,它将自动获得最新的totalPage并将其设置回原来的位置,这样就安全了。
translateGenre只是为了将体裁转换成文本,所以请不要打扰它。
但是,每当我刷新(F5)或浏览一段时间之后,我就会改变类型,它将得到同一个first array的复制(由于警告,我看到它有两个相同的条目)。由于我的滚动条总是停留在React-Infinite-Scroll-Component,的“末端”或default值( 0.8 ),这意味着当用户低于总高度的80%时,就会触发Infinite-Scroll-Component的next函数。
这是我的密码:
function AnimeGenre({ instance }) {
const { genre } = useParams()
const CancelToken = axios.CancelToken
const source = CancelToken.source()
const [animeList, setAnimeList] = useState([])
const [genreAnime, setGenreAnime] = useState("")
const [page, setPage] = useState(1)
const [totalPage, setTotalPage] = useState(91)
const [translateGenreAnime, setTranslateGenreAnime] = useState("")
const getList = async () => {
await instance
.get(`/anime/${genre}?page=${page}`, {
cancelToken: source.token,
})
.then((response) => {
const newPage = page + 1
setPage(newPage)
const newList = response.data.data.map((anime) => ({
slug: anime.slug,
thumbnail: anime.thumbnail,
name: anime.name,
views: anime.views,
}))
setTotalPage(response.data.pagination.totalPage)
setAnimeList((prev) => {
return [...new Set([...prev, ...newList])]
})
})
.catch((thrown) => {
if (axios.isCancel(thrown)) return
})
}
useEffect(() => {
if (genre === genreAnime) {
getList()
translateGenre()
} else {
window.onbeforeunload = function () {
window.scrollTo(0, 0)
}
window.scrollTo({
top: 0,
})
setPage(1)
setAnimeList([])
setGenreAnime(genre)
}
return () => {
source.cancel()
}
}, [genreAnime, genre])
const translateGenre = () => {
for (let i = 0; i < GENRES.length; i++) {
if (genreAnime == GENRES[i].slug) {
setTranslateGenreAnime(GENRES[i].name)
}
}
}
return (
<>
<div>
<h1>ANIME {translateGenreAnime}</h1>
</div>
<div className="anime-list">
<InfiniteScroll
initialScrollY={0}
style={{ overflow: "none" }}
dataLength={animeList.length}
next={getList}
hasMore={page === totalPage ? false : true}
loader={
<Row xs={1} sm={2} md={3} lg={4}>
{[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11].map((skeleton) => (
<Col key={skeleton}>
<Card>
<Card.Body style={{ maxHeight: "100%" }}>
<Skeleton
variant="rectangular"
width="100%"
height="192px"
animation="wave"
sx={{ bgcolor: "grey.900" }}
/>
<Skeleton
variant="text"
animation="wave"
sx={{ bgcolor: "grey.900" }}
/>
</Card.Body>
</Card>
</Col>
))}
</Row>
}
endMessage={<h4>NO MORE THINGS TO LOAD</h4>}
>
<Row xs={1} sm={2} md={3} lg={4}>
{animeList.map((anime) => (
<Col key={anime.slug}>
<Card>
<div className="card-container">
<Card.Img
variant="top"
src={anime.thumbnail}
fluid="true"
/>
<div className="overlay-card">
<a className="icon">{<BsFillPlayFill size={40} />}</a>
</div>
</div>
<Card.Body>
<Card.Title>
<TextTruncate
line={2}
element="span"
truncateText="…"
text={anime?.name}
/>
</Card.Title>
</Card.Body>
</Card>
<div className="w-100"></div>
</Col>
))}
</Row>
</InfiniteScroll>
</div>
<>
}只要scrollbar保持在顶端,它就能正常工作,因为它不会超过80%的高度的门槛。
工作一:

当我浏览并更改GENRE时失败,因为滚动条停留在底部,然后稍后它将执行scrollTo(0,0)。这不是我想要的,我想要的是相反的,它必须总是第一位.

第二个失败是当我按下使用F5按钮重新加载页面时。它会以某种方式显示出非常奇怪的(滚动条)。

更新:
我尝试禁用smooth-scrolling behavior并将滚动框设置为顶部的header组件,该组件有导航条,这样做似乎更合适,只要我在标题中单击某项内容或使用F5刷新,就可以将滚动条放到顶部。
但是,如果在第一次渲染时,我浏览页面和向下滚动的速度太快,我会得到重复的错误,因为我达到了阈值,而前面的函数还在执行中,如果我等待第一个呈现完全加载,那么我很好,是否有适当的方法做无限滚动,请给我一些简单的方式,我觉得我使它太复杂了。
发布于 2022-01-26 05:15:21
我想我做得对,但不太确定,“暂时”,效果很好。
我就是这么做的。
而不是
const newPage = page + 1
setPage(newPage)在getList函数中,我将其拆分为另一个名为scrollThreshold的函数。
const scrollThreshold = () => {
const newPage = page + 1
setPage(newPage)
}然后我开始
const PAGE_NUMBER = 1在组件之外(否则,我认为我应该使用useRef,或者只是保留它,以防万一)
然后,在useEffect中,我实现了另外一个依赖项,它是page状态,每当我得到新的page或page状态更改,或者genre更改时,它将再次运行useEffect。
然后,在InfiniteScroll组件中,我稍微修改一下
<InfiniteScroll>
...
next={getList}
...
</InfiniteScroll> 转到
<InfiniteScroll>
...
next={getList && scrollThreshold}
...
</InfiniteScroll> 因此,每当我向下滚动时,它都会触发getList和scrollThreshold,通过分离,它不会像我的第一段代码那样聚集在一起。到目前为止,它还在起作用,我不知道这是否好。
https://stackoverflow.com/questions/70857958
复制相似问题