Javascript 在ReactJS上单击列表中的更多项时保持滚动位置

Javascript 在ReactJS上单击列表中的更多项时保持滚动位置,javascript,reactjs,ecmascript-6,react-hooks,use-state,Javascript,Reactjs,Ecmascript 6,React Hooks,Use State,我在ReactJS商店有以下产品列表: {productsList.map((product) => ( <ProductItem product={product} /> )} 我需要保持滚动位置,因为这样用户必须滚动到顶部才能看到加载的新产品 我已尝试存储滚动位置,但更改是在列表增长之前完成的,因此不会发生任何情况: function nextPage() { const actualScrollPosition = window.pageYOffse

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

{productsList.map((product) => (
  <ProductItem
    product={product}
  />
)}
我需要保持滚动位置,因为这样用户必须滚动到顶部才能看到加载的新产品

我已尝试存储滚动位置,但更改是在列表增长之前完成的,因此不会发生任何情况:

function nextPage() {
  const actualScrollPosition = window.pageYOffset
  getMoreProducts().then((newProducts)=> {
    setProductsList(productsList.concat(newProducts))       //<- setState from React is async.
    window.scroll({ top: actualScrollPosition, behavior: "smooth" });
  })    
}
函数下一页(){
常量实际CrollPosition=window.pageYOffset
getMoreProducts()。然后((新产品)=>{

setProductsList(productsList.concat(newProducts))/您可以做的是保存
const savedHeight=document.body.offsetHeight
值,即完整文档高度。然后在产品加载后,将
window.scroll设置为(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.useEffect(() => {
    window.scroll({ top: pageYOffset });
  }, [productsList])

  return (
    <>
      {productsList.map((product) => (
        <ProductItem
          product={product}
        />
      ))}
      <button onClick={nextPage}>Load more</button>
    </>
  )
}
从“React”导入React
产品类型={
名称:string
}
const getMoreProducts=async()=>([{name:'foo'}])
export const ProductItem:React.FC=({product})=>{
返回{product.name}
}
导出常量ProductList:React.FC=()=>{
常量[productsList,setProductsList]=React.useState([])
让pageYOffset=window.pageYOffset
函数下一页(){
getMoreProducts()。然后((新产品)=>{
pageYOffset=window.pageYOffset
setProductsList(productsList.concat(新产品))
})    
}
React.useffect(()=>{
滚动({top:pageYOffset});
},[productsList])
返回(
{productsList.map((产品)=>(
))}
加载更多
)
}

在这种情况下,您也不希望出现
行为:“平滑”

很抱歉,刚刚在您的网站上测试过,但它不适用于scrollTop,相反,您可以使用scrollTo在窗口上滚动。已测试过,效果完美!
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.useEffect(() => {
    window.scroll({ top: pageYOffset });
  }, [productsList])

  return (
    <>
      {productsList.map((product) => (
        <ProductItem
          product={product}
        />
      ))}
      <button onClick={nextPage}>Load more</button>
    </>
  )
}