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 { useImperativeHandle } from 'react';
function MyInput({ ref }) {
useImperativeHandle(ref, () => {
return {
// ... seus métodos ...
};
}, []);
// ...
Parâmetros
-
ref
: Aref
que você recebeu como uma prop para o componenteMyInput
. -
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
:
Para expor um nó DOM ao elemento pai, passe a prop ref
para o nó.
function MyInput({ ref }) {
return <input ref={ref} />;
};
Com o código acima, uma ref para MyInput
receberá o nó DOM <input>
. No entanto, você pode expor um valor personalizado. Para customizar o identificador exposto, chame useImperativeHandle
no nível superior do seu componente:
import { useImperativeHandle } from 'react';
function MyInput({ ref }) {
useImperativeHandle(ref, () => {
return {
// ... seus métodos ...
};
}, []);
return <input />;
};
Note that in the code above, the ref
is no longer passed to the <input>
.
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} />;
};
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} /> </> ); }