useImperativeHandle
useImperativeHandle
est un Hook React qui vous permet de personnaliser la référence exposée comme ref.
useImperativeHandle(ref, createHandle, dependencies?)
Référence
useImperativeHandle(ref, createHandle, dependencies?)
Appelez useImperativeHandle
au niveau racine de votre composant pour personnaliser la ref qu’il expose :
import { forwardRef, useImperativeHandle } from 'react';
const MyInput = forwardRef(function MyInput(props, ref) {
useImperativeHandle(ref, () => {
return {
// ... vos méthodes ...
};
}, []);
// ...
Voir d’autres exemples ci-dessous.
Paramètres
-
ref
: laref
que vous avez reçue comme second argument depuis la fonction de rendu deforwardRef
. -
createHandle
: une fonction ne prenant aucun argument, qui renvoie la ref que vous souhaitez effectivement exposer. Cette ref peut être de n’importe quel type. En général, vous renverrez un objet avec les méthodes que vous souhaitez exposer. -
dependencies
optionnelles : la liste des valeurs réactives référencées par le code decreateHandle
. Les valeurs réactives comprennent les props, les variables d’état et toutes les variables et fonctions déclarées localement dans le corps de votre composant. Si votre linter est configuré pour React, il vérifiera que chaque valeur réactive concernée est bien spécifiée comme dépendance. La liste des dépendances doit avoir un nombre constant d’éléments et utiliser un littéral défini à la volée, du genre[dep1, dep2, dep3]
. React comparera chaque dépendance à sa valeur précédente au moyen de la comparaisonObject.is
. Si un nouveau rendu résulte d’une modification à une dépendance, ou si vous avez omis cet argument, la fonctioncreateHandle
sera réexécutée et la référence fraîchement créée sera affectée à la ref.
Valeur renvoyée
useImperativeHandle
renvoie undefined
.
Utilisation
Fournir une référence personnalisée au composant parent
Par défaut, les composants n’exposent pas leurs nœuds DOM aux composants parents. Par exemple, si vous souhaitez que le composant parent de MyInput
ait accès au nœud DOM <input>
, vous devez le permettre explicitement avec forwardRef
:
import { forwardRef } from 'react';
const MyInput = forwardRef(function MyInput(props, ref) {
return <input {...props} ref={ref} />;
});
Dans le code ci-avant, une ref à MyInput
recevra le nœud DOM <input>
. Cependant, vous pouvez plutôt exposer une valeur personnalisée. Pour définir vous-même la référence à exposer, appelez useImperativeHandle
au niveau racine de votre composant :
import { forwardRef, useImperativeHandle } from 'react';
const MyInput = forwardRef(function MyInput(props, ref) {
useImperativeHandle(ref, () => {
return {
// ... vos méthodes ...
};
}, []);
return <input {...props} />;
});
Remarquez que dans le code ci-avant, la ref
n’est plus transmise au <input>
.
Supposons par exemple que vous ne souhaitiez pas exposer l’intégralité du nœud DOM <input>
, mais seulement deux de ses méthodes : focus
et scrollIntoView
. Pour y parvenir, conservez le véritable nœud DOM dans une ref distincte, puis utilisez useImperativeHandle
pour exposer un objet avec seulement les méthodes que vous souhaitez permettre au composant parent d’appeler :
import { forwardRef, useRef, useImperativeHandle } from 'react';
const MyInput = forwardRef(function MyInput(props, ref) {
const inputRef = useRef(null);
useImperativeHandle(ref, () => {
return {
focus() {
inputRef.current.focus();
},
scrollIntoView() {
inputRef.current.scrollIntoView();
},
};
}, []);
return <input {...props} ref={inputRef} />;
});
Désormais, si le composant parent récupère une ref sur MyInput
, il ne pourra plus appeler que ses méthodes focus
et scrollIntoView
. Il n’aura pas un accès complet au nœud DOM <input>
sous-jacent.
import { useRef } from 'react'; import MyInput from './MyInput.js'; export default function Form() { const ref = useRef(null); function handleClick() { ref.current.focus(); // Ça ne marcherait pas, car le nœud DOM n'est pas exposé : // ref.current.style.opacity = 0.5; } return ( <form> <MyInput placeholder="Saisissez votre nom :" ref={ref} /> <button type="button" onClick={handleClick}> Modifier </button> </form> ); }
Exposer vos propres méthodes impératives
Les méthodes que vous exposez via un objet impératif n’ont pas l’obligation de correspondre à des méthodes du DOM. Par exemple, ce composant Post
expose une méthode scrollAndFocusAddComment
via un objet impératif. Elle permet au Page
parent de faire défiler la liste des commentaires et d’activer le champ de saisie lorsque vous cliquez sur le bouton :
import { useRef } from 'react'; import Post from './Post.js'; export default function Page() { const postRef = useRef(null); function handleClick() { postRef.current.scrollAndFocusAddComment(); } return ( <> <button onClick={handleClick}> Rédiger un commentaire </button> <Post ref={postRef} /> </> ); }