当scrollTop为零时在渲染后反应滚动位置

时间:2019-04-29 21:08:21

标签: reactjs scroll

我试图了解当可滚动div内的数据更改时反应的行为。

如果新数据包含一些当前可见的项目,则react将管理滚动位置以使这些元素保持可见。

想象一下两组元素:a,b,c,d,e,f,g,h,if,g,h,i,j,k,l,m,以及一个容器div,该容器div在垂直可滚动列表中显示它们,足够大,一次只能显示两个元素。

如果我向下滚动到元素f然后更改数据,则元素f仍然是可见的。我相信这是可行的,因为每个元素都有其自己的唯一密钥。

如果滚动位置为0,则行为会有所不同:呈现新元素后,如果我改回到第一组,则滚动将仍然为零,而不是在f上。如果您尝试此操作,则仅向下滚动一个像素即可正常工作。

下面是一个完整的最小工作示例:https://codepen.io/depsir/pen/OGGZPd

所以有两个问题:

  1. 正在这样做吗?如果是这样,是否有任何有关此行为的文档?
  2. 即使scrollTop = 0,我如何仍然保持渲染器中常见的可见元素?


编辑:我发现示例的行为在浏览器之间是不同的:firefox mobile和safari在任何情况下都保持滚动位置固定。

3 个答案:

答案 0 :(得分:0)

我发现此行为与浏览器有关,所以现在我可以回答我的第一个问题:

  

这样做有反应吗?如果是这样,是否有任何有关此行为的文档?

不,浏览器在做什么吗?您可以使用DOM api来简单地尝试:

// given a list of elements, in a scrollable container, 
// add a new element at first position
const list = document.getElementById("yourListId")  
list.insertBefore(getNewElement(), list.childNodes[0])

在这里您可以找到一个有效的示例:https://codepen.io/depsir/pen/GaRwWa

对于第二个问题,由于react没有做任何事情,因此很明显,必须手动管理此行为。

答案 1 :(得分:0)

您是否可以尝试传递key是除index之外的唯一值,它可能是key和任何随机值(例如new Date() + index)的组合。不建议react使用迭代器作为key道具,也可以看看here

您可以尝试

{state.map((k) => { var d = new Date(); return(<Element key={d +k} id={k} />)})}

{state.map((k) => { var random = Math.random(); return(<Element key={random +k} id={k} />)})}

这将尝试将滚动位置保持在您离开的位置。

答案 2 :(得分:0)

如果它在scrollTop == 0上不起作用,请使其更多:)。这是个骇人听闻的解决方案,但对我来说很完美。

function InfiniteScroll(){
  /* ... */
  const ref = React.useRef()
  React.useEffect(() => {
    const handle = () => {
      if(ref.current.scrollTop === 0){
        ref.current.scrollTop = 1;
      }
    };
    handle();
    ref.current.addEventListener('scroll', handle)
    return () => {
      ref.current.removeEventListener('scroll', handle)
    }
  }, [])

  return (
    /* ... */
      <div className='scroller' ref={ref}>
    /* ... */
  );
}

演示:https://codepen.io/anon/pen/KLdXKZ

您甚至可以在顶部添加边距以获得真正的像素完美效果。