javascript - Keep scrolling position when concat more items in a list on ReactJS - Stack Overflow

I have this list of products on a ReactJS store:{productsList.map((product) => (<ProductItemprod

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
Add a ment  | 

2 Answers 2

Reset to default 5

Try 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条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信