在 ReactJS 上的列表中连接更多项目时保持滚动位置

Dan*_*nha 6 javascript ecmascript-6 reactjs react-hooks use-state

我在 ReactJS 商店中有以下产品列表:

{productsList.map((product) => (
  <ProductItem
    product={product}
  />
)}
Run Code Online (Sandbox Code Playgroud)

当我在此列表中添加更多产品时,滚动位置将转到列表的末尾。添加更多产品的代码:

function nextPage() {
  getMoreProducts().then((newProducts)=> {
    setProductsList(productsList.concat(newProducts))
  })
}
Run Code Online (Sandbox Code Playgroud)

我需要保持滚动位置,因为这样用户必须滚动到顶部才能看到加载的新产品

我尝试存储滚动位置,但更改是在列表增长之前完成的,所以什么也没有发生:

function nextPage() {
  const actualScrollPosition = window.pageYOffset
  getMoreProducts().then((newProducts)=> {
    setProductsList(productsList.concat(newProducts))       //<- setState from React is async.
    window.scroll({ top: actualScrollPosition, behavior: "smooth" });
  })    
}
Run Code Online (Sandbox Code Playgroud)

Pat*_*her 4

尝试将滚动位置设置为由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>
    </>
  )
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,您也不希望behavior: "smooth".