6 votes

React Hooks - Passage de ref à l'enfant pour utiliser ScrollIntoView

J'ai deux composants. Un parent et un enfant.

À l'intérieur du composant parent, j'ai un bouton. Si l'utilisateur clique sur ce bouton, je veux faire un ScrollIntoView vers un autre bouton à l'intérieur du composant enfant.

Je suppose que je veux définir une référence au bouton de l'enfant de sorte que je puisse, à l'intérieur de l'événement onClick du bouton parent, faire un :

ref.scrollIntoView({block: 'end', behavior: 'smooth'});

qui fera défiler jusqu'au bouton dans le composant enfant.

Voici un exemple simplifié :

Fichier ParentComponent.jsx

import React, {useRef} from 'react';
import ChildComponent from './ChildComponent';

const ParentComponent = props => {
  const childReference = useRef(null);

  const onClick = () => {
    childReference.scrollIntoView({block: 'end', behavior: 'smooth'});
  }

  return (
    <>
      <...some other components>
      Cliquez pour être redirigé

  );
};

Fichier ChildComponent.jsx

import React from 'react';

const ChildComponent = (props, ref) => {

  const { name, value, description } = props;

  return (
    <...some other components>
    Vous devriez être redirigé vers moi
  );
};

ChildComponent.propTypes = {
  name: PropTypes.string.isRequired,
  value: PropTypes.number,
  description: PropTypes.string,
};

ChildComponent.defaultProps = {
  value: 0,
  description: '',
};

export default React.forwardRef(ChildComponent);

Je sais que le code ci-dessus ne fonctionne pas, c'était juste pour illustrer ce que j'essaie de réaliser.

J'ai vraiment essayé toutes les autres solutions que j'ai pu trouver en faisant des recherches sur Google et elles semblent toutes si faciles, mais aucune ne semble fonctionner pour mon cas d'utilisation. J'ai également essayé d'utiliser forwardRef, mais cela ne résout pas mon problème.

MISE À JOUR

Je suppose que j'ai été un peu vague sur ce qui ne fonctionne pas. J'ai reçu beaucoup de messages d'erreur différents avec la mise en œuvre.

Voici l'un d'entre eux:

Les composants de fonction ne peuvent pas recevoir de références. Les tentatives d'accès à cette référence échoueront. Vouliez-vous utiliser React.forwardRef()?

Solution

D'accord. Je pensais rassembler les éléments ici avec la solution fournie par @Vencovsky.

Voici l'implémentation complète avec les deux exemples de composants vus dans la question :

Fichier ParentComponent.jsx

import React, { useRef } from 'react';
import ChildComponent from './ChildComponent';

const ParentComponent = props => {
  const childReference = useRef(null);

  const scrollIntoView = () => {
    childReference.current.scrollIntoView({block: 'center', inline: 'center', behavior: 'smooth'});
  }

  return (
    <>
    <...some other component>
    Cliquez pour être redirigé

  );
};

export default ParentComponent;

Fichier ChildComponent.jsx

import React, {forwardRef} from 'react';
import PropTypes from 'prop-types';

const ChildComponent = forwardRef((props, ref) => {
  const { name, value, description } = props;

  return(
    <>
      <...some other components>
      Vous devriez être redirigé vers moi

  );
});

ChildComponent.propTypes = {
  name: PropTypes.string.isRequired,
  value: PropTypes.number,
  description: PropTypes.string,
};

ChildComponent.defaultProps = {
  value: 0,
  description: '',
};

export default ChildComponent;

5voto

Vencovsky Points 7756

Modifier 2 :

Je suppose que tu fais quelque chose comme

const ChildComponent = (props, ref) => { ... }

ChildComponent.propTypes = { ... }

export default React.forwardRef(ChildComponent)

Mais ce que tu dois faire, c'est passer propTypes après React.forwardRef, comme ceci :

const ChildComponent = (props, ref) => { ... }

const ForwardComponent = React.forwardRef(ChildComponent)

ForwardComponent.propTypes = { ... }

export default ForwardComponent

Une meilleure façon de le faire serait de

//                     en utilisant forwarRef
const ChildComponent = React.forwarRef((props, ref) => {

  const { name, value, description } = props;

  return (
    <...autres composants>
    Vous devriez être transféré vers moi
  );
});

Ensuite, vous n'auriez pas besoin de modifier propTypes et de créer un autre composant.

Modifier :

Comme dans ton Édition, je vois que tu as oublié d'utiliser React.forwardRef.

Vous devriez ajouter

export default React.forwardRef(ChildComponent)

Dans ton fichier ChildComponent (l'exporter avec forwardRef).


Qu'est-ce qui ne fonctionne pas ? Obtenez-vous une erreur ? Vous devriez mieux expliquer ce qui se passe, mais je vais essayer de deviner.

Il y a quelques éléments qui peuvent empêcher que cela fonctionne.

  1. Vous devez utiliser ref.current.foo au lieu de ref.foo

  2. Comme @JeroenWienk l'a dit :

    Il semble que votre bouton soit également un composant personnalisé. Êtes-vous sûr que la référence est transmise à l'élément de bouton HTML à l'intérieur ?

  3. Pour utiliser le deuxième paramètre d'un composant fonctionnel, vous devriez utiliser React.forwardRef. par exemple. export default React.forwardRef(ChildComponent)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X