我有一个聊天小部件,每当我向上滚动时,它就会弹出一个消息数组。我现在面临的问题是,当消息加载时,滑块固定在顶部。我想让它关注上一个数组的最后一个索引元素。我发现我可以通过传递索引来进行动态引用,但我也需要知道使用哪种滚动函数来实现这一点

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

  render() {

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

当前回答

也许有人会遇到像我这样的情况

https://reactjs.org/docs/hooks-faq.html#how-can-i-measure-a-dom-node

如何度量DOM节点? 测量DOM节点位置或大小的一种基本方法是使用回调ref。每当ref附加到不同的节点时,React就会调用该回调。下面是一个小演示:

function MeasureExample() {
  const [height, setHeight] = useState(0);

  const measuredRef = useCallback(node => {
    if (node !== null) {
      setHeight(node.getBoundingClientRect().height);// you can scroll in this line 
    }
  }, []);

  return (
    <>
      <h1 ref={measuredRef}>Hello, world</h1>
      <h2>The above header is {Math.round(height)}px tall</h2>
    </>
  );
}

在本例中,我们没有选择useRef,因为对象引用不会通知我们当前引用值的更改。使用回调引用可以确保即使稍后子组件显示了被测量的节点(例如,在响应单击时),我们仍然会在父组件中得到关于它的通知,并可以更新测量值。

注意,我们将[]作为依赖数组传递给useCallback。这确保了我们的ref回调在重新渲染之间不会改变,所以React不会不必要地调用它。

在这个例子中,回调ref只会在组件挂载和卸载时被调用,因为呈现的组件在任何重新呈现器中都保持存在。如果你想在组件调整大小时收到通知,你可以使用ResizeObserver或在其上构建的第三方Hook。

其他回答

下面是你可以用来解决这个问题的类组件代码片段:

这种方法使用了ref,并且平滑地滚动到目标ref

import React, { Component } from 'react'

export default class Untitled extends Component {
  constructor(props) {
    super(props)
    this.howItWorks = React.createRef() 
  }

  scrollTohowItWorks = () =>  window.scroll({
    top: this.howItWorks.current.offsetTop,
    left: 0,
    behavior: 'smooth'
  });

  render() {
    return (
      <div>
       <button onClick={() => this.scrollTohowItWorks()}>How it works</button>
       <hr/>
       <div className="content" ref={this.howItWorks}>
         Lorem ipsum dolor, sit amet consectetur adipisicing elit. Nesciunt placeat magnam accusantium aliquid tenetur aspernatur nobis molestias quam. Magnam libero expedita aspernatur commodi quam provident obcaecati ratione asperiores, exercitationem voluptatum!
       </div>
      </div>
    )
  }
}

只需找到您已经确定的元素的顶部位置https://www.w3schools.com/Jsref/prop_element_offsettop.asp,然后通过scrollTo方法https://www.w3schools.com/Jsref/met_win_scrollto.asp滚动到这个位置

像这样的东西应该工作:

handleScrollToElement(event) {
  const tesNode = ReactDOM.findDOMNode(this.refs.test)
  if (some_logic){
    window.scrollTo(0, tesNode.offsetTop);
  }
}

render() {

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

更新:

因为React v16.3 React. createref()是首选

constructor(props) {
  super(props);
  this.myRef = React.createRef();
}

handleScrollToElement(event) {
  if (<some_logic>){
    window.scrollTo(0, this.myRef.current.offsetTop);
  }
}

render() {

  return (
    <div>
      <div ref={this.myRef}></div>
    </div>)
}

最好的方法是使用element。scrollIntoView({behavior: 'smooth'})。这将以漂亮的动画将元素滚动到视图中。

当你将它与React的useRef()结合使用时,可以通过以下方式完成。

import React, { useRef } from 'react'

const Article = () => {
  const titleRef = useRef()

  function handleBackClick() {
      titleRef.current.scrollIntoView({ behavior: 'smooth' })
  }

  return (
      <article>
            <h1 ref={titleRef}>
                A React article for Latin readers
            </h1>

            // Rest of the article's content...

            <button onClick={handleBackClick}>
                Back to the top
            </button>
        </article>
    )
}

当你想要滚动到React组件时,你需要将引用转发给渲染的元素。本文将深入探讨这个问题。

<div id="componentToScrollTo"><div>

<a href='#componentToScrollTo'>click me to scroll to this</a>

我可能迟到了,但我试图实现动态引用到我的项目的正确方式和所有的答案,我已经找到,直到知道不是安静的满足我的喜欢,所以我想出了一个解决方案,我认为是简单的,并使用本机和推荐的反应方式来创建引用。

有时,您会发现文档的编写方式假设您有一个已知的视图数量,而在大多数情况下,这个数字是未知的,因此您需要一种方法来解决这个问题,在这种情况下,创建动态引用到您需要在类中显示的未知视图数量

所以我能想到的最简单且完美无缺的解决方案是这样做的

class YourClass extends component {

state={
 foo:"bar",
 dynamicViews:[],
 myData:[] //get some data from the web
}

inputRef = React.createRef()

componentDidMount(){
  this.createViews()
}


createViews = ()=>{
const trs=[]
for (let i = 1; i < this.state.myData.lenght; i++) {

let ref =`myrefRow ${i}`

this[ref]= React.createRef()

  const row = (
  <tr ref={this[ref]}>
<td>
  `myRow ${i}`
</td>
</tr>
)
trs.push(row)

}
this.setState({dynamicViews:trs})
}

clickHandler = ()=>{

//const scrollToView = this.inputRef.current.value
//That to select the value of the inputbox bt for demostrate the //example

value=`myrefRow ${30}`

  this[value].current.scrollIntoView({ behavior: "smooth", block: "start" });
}


render(){

return(
<div style={{display:"flex", flexDirection:"column"}}>
<Button onClick={this.clickHandler}> Search</Button>
<input ref={this.inputRef}/>
<table>
<tbody>
{this.state.dynamicViews}
<tbody>
<table>
</div>


)

}

}

export default YourClass

这样,滚动就会转到你要找的任何一行。

干杯,希望它能帮助别人