如何滚动到元素?React 16.8 +, 功能组件React 16.3 +,类组件类组件 - 引用回调

2022-08-29 23:35:17

我有一个聊天小部件,每次向上滚动时都会拉出一组消息。我现在面临的问题是,当消息加载时,滑块保持在顶部固定。我希望它专注于上一个数组中的最后一个索引元素。我发现我可以通过传递索引来制作动态引用,但我还需要知道使用哪种滚动函数来实现这一点

 handleScrollToElement(event) {
    const tesNode = ReactDOM.findDOMNode(this.refs.test)
    if (some_logic){
      //scroll to testNode      
    }
  }

  render() {

    return (
      <div>
        <div ref="test"></div>
      </div>)
  }

答案 1

React 16.8 +, 功能组件

const ScrollDemo = () => {
   const myRef = useRef(null)

   const executeScroll = () => myRef.current.scrollIntoView()    
   // run this function from an event handler or an effect to execute scroll 

   return (
      <> 
         <div ref={myRef}>Element to scroll to</div> 
         <button onClick={executeScroll}> Click to scroll </button> 
      </>
   )
}

单击此处查看有关 StackBlits 的完整演示

React 16.3 +,类组件

class ReadyToScroll extends Component {
    constructor(props) {
        super(props)
        this.myRef = React.createRef()  
    }

    render() {
        return <div ref={this.myRef}>Element to scroll to</div> 
    }  

    executeScroll = () => this.myRef.current.scrollIntoView()
    // run this method to execute scrolling. 
}

类组件 - 引用回调

class ReadyToScroll extends Component {  
    render() {
        return <div ref={ (ref) => this.myRef=ref }>Element to scroll to</div>
    } 

    executeScroll = () => this.myRef.scrollIntoView()
    // run this method to execute scrolling. 
}

不要使用字符串引用。

字符串引用会损害性能,不可组合,并且正在退出(2018 年 8 月)。

字符串引用存在一些问题,被视为旧版,并且可能会在将来的某个版本中被删除。[官方 React 文档]

资源 1资源 2

可选:平滑滚动动画

/* css */
html {
    scroll-behavior: smooth;
}

将引用传递给孩子

我们希望 ref 附加到 dom 元素,而不是 react 组件。因此,在将其传递给子组件时,我们无法命名 prop ref。

const MyComponent = () => {
    const myRef = useRef(null)
    return <ChildComp refProp={myRef}></ChildComp>
} 

然后将 ref prop 附加到 dom 元素。

const ChildComp = (props) => {
    return <div ref={props.refProp} />
}

答案 2

这对我有用

this.anyRef.current.scrollIntoView({ behavior: 'smooth', block: 'start' })

编辑:我想根据评论对此进行扩展。

const scrollTo = (ref) => {
  if (ref && ref.current /* + other conditions */) {
    ref.current.scrollIntoView({ behavior: 'smooth', block: 'start' })
  }
}

<div ref={scrollTo}>Item</div>