useImperativeHandle
useImperativeHandle è un Hook React che ti permette di personalizzare l’handle esposto come ref.
useImperativeHandle(ref, createHandle, dependencies?)Reference
useImperativeHandle(ref, createHandle, dependencies?)
Chiama useImperativeHandle al top level del tuo componente per personalizzare l’handle del ref che espone:
import { useImperativeHandle } from 'react';
function MyInput({ ref }) {
useImperativeHandle(ref, () => {
return {
// ... i tuoi metodi ...
};
}, []);
// ...Parameters
-
ref: Larefche hai ricevuto come prop del componenteMyInput. -
createHandle: Una funzione che non accetta argomenti e restituisce l’handle del ref che vuoi esporre. L’handle del ref può essere di qualsiasi tipo. Di solito, restituirai un oggetto con i metodi che vuoi esporre. -
optional
dependencies: L’elenco di tutti i valori reattivi referenziati all’interno del codice dicreateHandle. I valori reattivi includono props, state e tutte le variabili e funzioni dichiarate direttamente nel corpo del componente. Se il tuo linter è configurato per React, verificherà che ogni valore reattivo sia specificato correttamente come dipendenza. L’elenco delle dipendenze deve avere un numero costante di elementi ed essere scritto inline come[dep1, dep2, dep3]. React confronterà ogni dipendenza con il suo valore precedente usando il confrontoObject.is. Se una ri-renderizzazione ha comportato un cambiamento in qualche dipendenza, o se hai omesso questo argomento, la tua funzionecreateHandleverrà rieseguita e l’handle appena creato verrà assegnato alla ref.
Returns
useImperativeHandle restituisce undefined.
Usage
Esporre un handle ref personalizzato al componente genitore
Per esporre un nodo DOM al componente genitore, passa la prop ref al nodo.
function MyInput({ ref }) {
return <input ref={ref} />;
};Con il codice sopra, una ref a MyInput riceverà il nodo DOM <input>. Tuttavia, puoi esporre un valore personalizzato al suo posto. Per personalizzare l’handle esposto, chiama useImperativeHandle al top level del tuo componente:
import { useImperativeHandle } from 'react';
function MyInput({ ref }) {
useImperativeHandle(ref, () => {
return {
// ... i tuoi metodi ...
};
}, []);
return <input />;
};Nota che nel codice sopra, la ref non viene più passata all’<input>.
Ad esempio, supponiamo che tu non voglia esporre l’intero nodo DOM <input>, ma che tu voglia esporre due dei suoi metodi: focus e scrollIntoView. Per farlo, mantieni il DOM del browser reale in una ref separata. Poi usa useImperativeHandle per esporre un handle con solo i metodi che vuoi che il componente genitore chiami:
import { useRef, useImperativeHandle } from 'react';
function MyInput({ ref }) {
const inputRef = useRef(null);
useImperativeHandle(ref, () => {
return {
focus() {
inputRef.current.focus();
},
scrollIntoView() {
inputRef.current.scrollIntoView();
},
};
}, []);
return <input ref={inputRef} />;
};Ora, se il componente genitore ottiene una ref a MyInput, sarà in grado di chiamare i metodi focus e scrollIntoView su di esso. Tuttavia, non avrà pieno accesso al nodo DOM <input> sottostante.
import { useRef } from 'react'; import MyInput from './MyInput.js'; export default function Form() { const ref = useRef(null); function handleClick() { ref.current.focus(); // Non funzionerà perché il nodo DOM non è esposto: // ref.current.style.opacity = 0.5; } return ( <form> <MyInput placeholder="Enter your name" ref={ref} /> <button type="button" onClick={handleClick}> Edit </button> </form> ); }
Esporre i tuoi metodi imperativi
I metodi che esponi tramite un handle imperativo non devono corrispondere esattamente ai metodi del DOM. Ad esempio, questo componente Post espone un metodo scrollAndFocusAddComment tramite un handle imperativo. Questo permette al componente genitore Page di scorrere l’elenco dei commenti e mettere il focus sul campo di input quando clicchi su un pulsante:
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}> Write a comment </button> <Post ref={postRef} /> </> ); }