在 ReactJS 的列表中连接更多项目时保持滚动位置
Keep scrolling position when concat more items in a list on ReactJS
我在 ReactJS 商店中有这个产品列表:
{productsList.map((product) => (
<ProductItem
product={product}
/>
)}
当我在此列表中添加更多产品时,滚动位置转到列表末尾。添加更多产品的代码:
function nextPage() {
getMoreProducts().then((newProducts)=> {
setProductsList(productsList.concat(newProducts))
})
}
我需要保持滚动位置,因为这样用户必须滚动到顶部才能看到加载的新产品。
我已经尝试存储滚动位置,但是更改是在列表增长之前完成的,所以没有任何反应:
function nextPage() {
const actualScrollPosition = window.pageYOffset
getMoreProducts().then((newProducts)=> {
setProductsList(productsList.concat(newProducts)) //<- setState from React is async.
window.scroll({ top: actualScrollPosition, behavior: "smooth" });
})
}
您可以做的是保存 const savedHeight = document.body.offsetHeight
值,即整个文档的高度。然后在产品加载后,设置 window.scrollTo(0, savedHeight)
因为 body 似乎负责页面上的滚动。这将使屏幕停留在单击加载按钮时的相同位置。
尝试将 useLayoutEffect
中的滚动位置设置为 productsList
:
的更改触发
import React from 'react'
type Product = {
name: string
}
const getMoreProducts = async () => ([{name:'foo'}])
export const ProductItem: React.FC<{ product: Product> = ({ product }) => {
return <div>{product.name}</div>
}
export const ProductList: React.FC = () => {
const [productsList, setProductsList] = React.useState([])
let pageYOffset = window.pageYOffset
function nextPage() {
getMoreProducts().then((newProducts)=> {
pageYOffset = window.pageYOffset
setProductsList(productsList.concat(newProducts))
})
}
React.useLayoutEffect(() => {
window.scroll({ top: pageYOffset });
}, [productsList])
return (
<>
{productsList.map((product) => (
<ProductItem
product={product}
/>
))}
<button onClick={nextPage}>Load more</button>
</>
)
}
在这种情况下,您也不想要 behavior: "smooth"
。
我在 ReactJS 商店中有这个产品列表:
{productsList.map((product) => (
<ProductItem
product={product}
/>
)}
当我在此列表中添加更多产品时,滚动位置转到列表末尾。添加更多产品的代码:
function nextPage() {
getMoreProducts().then((newProducts)=> {
setProductsList(productsList.concat(newProducts))
})
}
我需要保持滚动位置,因为这样用户必须滚动到顶部才能看到加载的新产品。
我已经尝试存储滚动位置,但是更改是在列表增长之前完成的,所以没有任何反应:
function nextPage() {
const actualScrollPosition = window.pageYOffset
getMoreProducts().then((newProducts)=> {
setProductsList(productsList.concat(newProducts)) //<- setState from React is async.
window.scroll({ top: actualScrollPosition, behavior: "smooth" });
})
}
您可以做的是保存 const savedHeight = document.body.offsetHeight
值,即整个文档的高度。然后在产品加载后,设置 window.scrollTo(0, savedHeight)
因为 body 似乎负责页面上的滚动。这将使屏幕停留在单击加载按钮时的相同位置。
尝试将 useLayoutEffect
中的滚动位置设置为 productsList
:
import React from 'react'
type Product = {
name: string
}
const getMoreProducts = async () => ([{name:'foo'}])
export const ProductItem: React.FC<{ product: Product> = ({ product }) => {
return <div>{product.name}</div>
}
export const ProductList: React.FC = () => {
const [productsList, setProductsList] = React.useState([])
let pageYOffset = window.pageYOffset
function nextPage() {
getMoreProducts().then((newProducts)=> {
pageYOffset = window.pageYOffset
setProductsList(productsList.concat(newProducts))
})
}
React.useLayoutEffect(() => {
window.scroll({ top: pageYOffset });
}, [productsList])
return (
<>
{productsList.map((product) => (
<ProductItem
product={product}
/>
))}
<button onClick={nextPage}>Load more</button>
</>
)
}
在这种情况下,您也不想要 behavior: "smooth"
。