ReactJS comment faire défiler jusqu'à un élément

J'ai un widget de chat qui tire un tableau de messages chaque fois que je fais défiler vers le haut. Le problème auquel je suis confronté maintenant est que le curseur reste fixé en haut lorsque les messages se chargent, je veux qu'il se concentre sur le dernier élément d'index du tableau précédent. J'ai compris que je peux faire des refs dynamiques en passant index, mais j'aurais aussi besoin de savoir quel type de fonction de défilement utiliser pour y parvenir

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

  render() {

    return (
      <div>
        <div ref="test"></div>
      </div>)
  }
25
demandé sur e_mam106 2017-04-16 23:33:59

7 réponses

Août 2018 - N'utilisez pas de refs de chaîne.

Les conseils de L'équipe React contre l'utilisation de refs string, car "les refs string ont des problèmes, sont considérés comme hérités et sont susceptibles d'être supprimés dans l'une des futures versions."ressource

Création d'un objet ref.

Les Refs peuvent être créés sur des éléments dom, ou des composants de classe, mais pas sur des composants fonctionnels. Nous allons démontrer avec un div.

Méthode 1

class MyComponent extends React.Component {
    constructor(props) {
        super(props);
        this.myRef = React.createRef();
    }
    render() {
        return <div ref={this.myRef}
    }
}

Méthode 2

class MyComponent extends React.Component {
    render() {
        return <div ref={ re => { this.myRef = re } }
    }
}

Faites Défiler Jusqu'À La Méthode

class MyComponent extends React.Component {
    scrollToDomRef = () => {
        const myDomNode = ReactDOM.findDOMNode(this.myRef.current)
        myDomNode.scrollIntoView()
    }
}

Au Lieu de domNode.scrollIntoView() vous pouvez aussi utiliser window.scrollTo(0, tesNode.offsetTop). Vous pouvez utiliser cette formule pour mieux ajuster la position finale après le défilement. Par exemple, si vous voulez faire défiler jusqu'à 10 px au-dessus de l'élément window.scrollTo(0, myDomNode.offsetTop-10)

15
répondu Ben 2018-10-02 13:18:12

Trouvez simplement la position supérieure de l'élément que vous avez déjà déterminé https://www.w3schools.com/Jsref/prop_element_offsettop.asp puis faites défiler jusqu'à cette position via scrollTo Méthode https://www.w3schools.com/Jsref/met_win_scrollto.asp

Quelque chose comme ça devrait fonctionner:

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>)
}

Mise à jour:

Depuis Réagir v16.3 le React.createRef() est préféré

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

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

render() {

  return (
    <div>
      <div ref={this.myRef}></div>
    </div>)
}
25
répondu Roman Maksimov 2018-08-18 10:09:18

L'utilisation de findDOMNode sera finalement obsolète.

La méthode préférée consiste à utiliser des références de rappel.

Https://github.com/yannickcr/eslint-plugin-react/issues/678#issue-165177220

12
répondu sww314 2018-01-02 17:45:38

Vous pouvez également utiliser la méthode scrollIntoView pour faire défiler jusqu'à un élément donné.

handleScrollToElement(event) {
const tesNode = ReactDOM.findDOMNode(this.refs.test)
 if (some_logic){
  tesNode.scrollIntoView();
  }
 }

 render() {
  return (
   <div>
     <div ref="test"></div>
   </div>)
}
7
répondu Farshad J 2018-04-23 12:45:37

Vous pouvez essayer de cette façon:

 handleScrollToElement = e => {
    const elementTop = this.gate.offsetTop;
    window.scrollTo(0, elementTop);
 };

 render(){
  return(
      <h2 ref={elem => (this.gate = elem)}>Payment gate</h2>
 )}
6
répondu jirina Brezinova 2018-04-17 10:16:16

Vous pouvez utiliser quelque chose comme componentDidUpdate

componentDidUpdate = function() {
  var elem = document.getElementById('yourId'); 
  elem.scrollTop = elem.scrollHeight;
};
4
répondu Raviteja 2018-02-16 10:09:13

Cela a fonctionné pour moi

this.anyRef.current.scrollIntoView({ behavior: 'smooth', block: 'start' })
0
répondu chii 2018-09-27 02:41:35