简体   繁体   English

使用 React useEffect 在页面加载时滚动到元素中的某个位置

[英]Scrolling to a position in an element on page load with React useEffect

I'd like to scroll to a given horizontal position in an element immediately after it's rendered by React.我想在 React 渲染元素后立即滚动到元素中的给定水平位置。 For context, I'm using Next.js with server-side rendering, so useLayoutEffect isn't an option.对于上下文,我使用 Next.js 和服务器端渲染,所以useLayoutEffect不是一个选项。

export default function WideElement () {
  const ref = useRef(null)

  useEffect(function () {
    ref.current.scrollLeft = 1000
  }, [])

  return (
    <Container ref={ref}>
      ...
    </Container>
  )
}

However, the above code doesn't scroll when the page loads.但是,当页面加载时,上面的代码不会滚动。 Here the ... represents a long list of child elements that stack horizontally and overflow the container.这里的...代表一长串子元素,它们水平堆叠并溢出容器。

I have noticed that if I impose an artificial delay on the scroll, it seems to work fine, and Container is immediately scrolled 1000 pixels to the left.我注意到,如果我对滚动施加人为延迟,它似乎可以正常工作,并且Container会立即向左滚动 1000 像素。

export default function WideElement () {
  const ref = useRef(null)

  useEffect(function () {
    setTimeout(function() {
      ref.current.scrollLeft = 1000
    }, 1000)
  }, [])

  return (
    <Container ref={ref}>
      ...
    </Container>
  )
}

I think I might be misunderstanding useEffect .我想我可能误解了useEffect What am I missing, and how could I make this work?我错过了什么,我怎么能让这个工作?

if you require that the ref be available to do something when it mounts, you can use a callback method passed to the ref attribute instead of relying on a timeout.如果您要求 ref 在挂载时可以执行某些操作,您可以使用传递给 ref 属性的回调方法,而不是依赖超时。 The callback method accepts the node as a parameter, and you can do with it what you will from there.回调方法接受节点作为参数,您可以从那里对它进行任何操作。

It also gives you opportunity to react to any ref changes, or mounting/unmounting它还使您有机会对任何参考更改或安装/卸载做出反应

This should be more reliable than a timeout.这应该比超时更可靠。

export default function WideElement () {
  const ref = useRef(null);

  const setRef = useCallback((node) => {
     if (node) {
         node.scrollLeft = 1000;  
     }
     ref.current = node;               
  },[]) 

  return (
    <Container ref={setRef}>
      ...
    </Container>
  )
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM