useImperativeHandle
useImperativeHandle
é um React Hook que permite customizar o identificador exposto como ref.
useImperativeHandle(ref, createHandle, dependencies?)
Referência
useImperativeHandle(ref, createHandle, dependencies?)
Chame useImperativeHandle
no nível superior do seu componente para customizar o identificador de referência que ele expõe:
import { forwardRef, useImperativeHandle } from 'react';
const MyInput = forwardRef(function MyInput(props, ref) {
useImperativeHandle(ref, () => {
return {
// ... seus métodos ...
};
}, []);
// ...
Parâmetros
-
ref
: Aref
que você recebeu como segundo argumento da função de renderizaçãoforwardRef
. -
createHandle
: Uma função que não aceita argumentos e retorna o identificador de referência que você deseja expor. Essa identificador de referência pode ter qualquer tipo. Normalmente, você retornará um objeto com os métodos que deseja expor. -
opcional
dependencies
: A lista de todos os valores reativos referenciados dentro do códigocreateHandle
. Os valores reativos incluem propriedades, estado, e todas as variáveis e funções declaradas diretamente dentro do corpo do seu componente. Se o seu linter estiver configurado para React, ele verificará se cada valor reativo está especificado corretamente como uma dependência. A lista de dependências devem ter um número constante de items e ser escrito inline como[dep1, dep2, dep3]
. O React comparará cada dependência com seu valor anterior usando a comparaçãoObject.is
. Se uma nova renderização resultou em uma alteração em alguma dependência, ou se você omitiu este argumento, sua funçãocreateHandle
será executada novamente e o identificador recém-criado será atribuído à ref.
Retorna
useImperativeHandle
retorna undefined
.
Uso
Expondo um identificador de referência customizado ao componente pai
Por padrão, os componentes não expõem seus nós DOM aos componentes pai. Por exemplo, se você deseja que o componente pai de MyInput
tenha acesso ao nó DOM <input>
, você deve optar por forwardRef
:
import { forwardRef } from 'react';
const MyInput = forwardRef(function MyInput(props, ref) {
return <input {...props} ref={ref} />;
});
Com o código acima, uma referência para MyInput
receberá o nó DOM <input>
. No entanto, você pode expor um valor customizado. Para customizar o identificador exposto, chame useImperativeHandle
no nível superior do seu componente:
import { forwardRef, useImperativeHandle } from 'react';
const MyInput = forwardRef(function MyInput(props, ref) {
useImperativeHandle(ref, () => {
return {
// ... seus métodos ...
};
}, []);
return <input {...props} />;
});
Note que no código acima, a ref
não é mais encaminhado para o <input>
.
Por exemplo, suponha que você não queira expor todo o nó DOM <input>
, mas você deseja expor dois de seus métodos: focus
e scrollIntoView
. Para fazer isso, mantenha o DOM real do navegador em uma referência separada. Em seguida, use useImperativeHandle
para expor um identificador com apenas os métodos que você deseja que o componente pai chame:
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} />;
});
Agora, se o componente pai obtiver uma referência para MyInput
, ele será capaz de chamar os métodos focus
e scrollIntoView
nele. No entanto, ele não terá acesso total ao nó DOM <input>
subjacente.
import { useRef } from 'react'; import MyInput from './MyInput.js'; export default function Form() { const ref = useRef(null); function handleClick() { ref.current.focus(); // Isso não funcionará porque o nó DOM não está exposto: // ref.current.style.opacity = 0.5; } return ( <form> <MyInput placeholder="Enter your name" ref={ref} /> <button type="button" onClick={handleClick}> Edit </button> </form> ); }
Expondo seus próprios métodos imperativos
Os métodos que você expõe por meio de um identificador imperativo não precisam corresponder exatamente aos métodos DOM. Por exemplo, este componente Post
expõe um método scrollAndFocusAddComment
por meio de um identificador imperativo. Isso permite que a Page
pai role a lista de comentários e foque no campo de entrada quando você clica no botão:
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} /> </> ); }