I have this list of products on a ReactJS store:
{productsList.map((product) => (
<ProductItem
product={product}
/>
)}
When I add more products in this list, the scroll position goes to the end of the list. The code to add more products:
function nextPage() {
getMoreProducts().then((newProducts)=> {
setProductsList(productsList.concat(newProducts))
})
}
I need to keep the scroll position, because this way the user have to scroll to top to see the loaded new products.
I have try storing the scroll position, but the changes are done before the list grow, so nothing happens:
function nextPage() {
const actualScrollPosition = window.pageYOffset
getMoreProducts().then((newProducts)=> {
setProductsList(productsList.concat(newProducts)) //<- setState from React is async.
window.scroll({ top: actualScrollPosition, behavior: "smooth" });
})
}
I have this list of products on a ReactJS store:
{productsList.map((product) => (
<ProductItem
product={product}
/>
)}
When I add more products in this list, the scroll position goes to the end of the list. The code to add more products:
function nextPage() {
getMoreProducts().then((newProducts)=> {
setProductsList(productsList.concat(newProducts))
})
}
I need to keep the scroll position, because this way the user have to scroll to top to see the loaded new products.
I have try storing the scroll position, but the changes are done before the list grow, so nothing happens:
function nextPage() {
const actualScrollPosition = window.pageYOffset
getMoreProducts().then((newProducts)=> {
setProductsList(productsList.concat(newProducts)) //<- setState from React is async.
window.scroll({ top: actualScrollPosition, behavior: "smooth" });
})
}
Share
Improve this question
edited Mar 3, 2021 at 11:06
Danilo Cunha
asked Sep 1, 2020 at 19:49
Danilo CunhaDanilo Cunha
1,2882 gold badges15 silver badges24 bronze badges
2 Answers
Reset to default 5Try setting the scroll position in a useLayoutEffect
triggered by the change to 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>
</>
)
}
In this case, you also don't want the behavior: "smooth"
.
What you can do is save the const savedHeight = document.body.offsetHeight
value which is the full document height. Then after the products have loaded, set window.scrollTo(0, savedHeight)
since body seem to be in charge for the scrolling on your page. This will make the screen stay at the same place as when the load button was clicked.
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744686368a4587942.html
评论列表(0条)