在 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"