useImperativeHandle
useImperativeHandle
adalah sebuah React Hook yang memungkinkan Anda menyesuaikan penanganan yang diekspos sebagai ref.
useImperativeHandle(ref, createHandle, dependencies?)
Referensi
useImperativeHandle(ref, createHandle, dependencies?)
Panggil fungsi useImperativeHandle
di tingkat teratas komponen Anda untuk menyesuaikan penanganan yang diekspos oleh ref:
import { forwardRef, useImperativeHandle } from 'react';
const MyInput = forwardRef(function MyInput(props, ref) {
useImperativeHandle(ref, () => {
return {
// ... your methods ...
};
}, []);
// ...
Lihat lebih banyak contoh di bawah.
Parameter
-
ref
: ref yang Anda terima sebagai argumen kedua dari fungsi renderforwardRef
. -
createHandle
: Sebuah fungsi yang tidak mengambil argumen dan mengembalikan penanganan ref yang ingin Anda ekspos. Penanganan ref tersebut dapat memiliki tipe apa pun. Biasanya, Anda akan mengembalikan sebuah objek dengan sekumpulan metode yang ingin Anda ekspos. -
dependencies
opsional: Daftar semua nilai reaktif yang dirujuk di dalam kodesetup
. Nilai reaktif termasuk props, state, dan semua variabel dan fungsi yang dideklarasikan langsung di dalam tubuh komponen. Jika linter Anda telah dikonfigurasi untuk React, maka linter tersebut akan memverifikasi bahwa setiap nilai reaktif sudah diatur dengan benar sebagai dependensi. Daftar dependensi ini harus memiliki jumlah item yang konstan dan ditulis secara inline seperti[dep1, dep2, dep3]
. React akan membandingkan setiap dependensi dengan nilai lama menggunakan perbandinganObject.is
. Jika sebuah render ulang menghasilkan sebuah perubahan terhadap beberapa dependency, atau jika Anda menghilangkan argumen ini, fungsicreateHandle
Anda akan dijalankan ulang, dan penanganan yang baru dibuat akan ditetapkan kepadaref
tersebut.
Kembalian
useImperativeHandle
mengembalikan undefined
.
Penggunaan
Mengekspos sebuah penanganan ref kustom kepada komponen induk
Secara bawaan, komponen tidak mengekspos simpul-simpul DOM (DOM Nodes) kepada komponen induk. Sebagai contoh, jika Anda menginginkan komponen induk dari MyInput
untuk memiliki akses terhadap simpul DOM dari <input>
, Anda harus menyertakannya dengan forwardRef
:
import { forwardRef } from 'react';
const MyInput = forwardRef(function MyInput(props, ref) {
return <input {...props} ref={ref} />;
});
Dengan kode di atas, sebuah ref yang diteruskan ke komponen MyInput
akan menerima simpul DOM dari <input>
. Namun, Anda dapat mengekspos sebuah nilai kustom. Untuk mengkustom penanganan yang diekspos, panggil fungsi useImperativeHandle
di tingkat atas komponen Anda:
import { forwardRef, useImperativeHandle } from 'react';
const MyInput = forwardRef(function MyInput(props, ref) {
useImperativeHandle(ref, () => {
return {
// ... your methods ...
};
}, []);
return <input {...props} />;
});
Perlu dicatat bahwa dalam kode di atas, ref
tidak lagi diteruskan kepada <input>
.
Sebagai contoh, jika Anda tidak ingin mengekspos keseluruhan simpul DOM dari <input>
, namun Anda ingin mengekspos dua methods yang tersedia di dalamnya: focus
dan scrollIntoView
. Untuk melakukan hal tersebut, pertahankan DOM peramban yang asli ke dalam ref yang terpisah. Kemudian gunakan useImperativeHandle
untuk mengekspos sebuah penanganan hanya dengan methods yang ingin Anda panggil melalui komponen induk:
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} />;
});
Sekarang, jika komponen induk mendapatkan sebuah ref yang merujuk pada MyInput
, komponen tersebut akan dapat memanggil method focus
dan scrollIntoView
. Meskipun begitu, komponen induk tersebut tidak akan memiliki akses penuh terhadap simpul DOM <input>
yang mendasarinya.
import { useRef } from 'react'; import MyInput from './MyInput.js'; export default function Form() { const ref = useRef(null); function handleClick() { ref.current.focus(); // This won't work because the DOM node isn't exposed: // ref.current.style.opacity = 0.5; } return ( <form> <MyInput label="Enter your name:" ref={ref} /> <button type="button" onClick={handleClick}> Edit </button> </form> ); }
Mengekspos methods imperatif Anda sendiri
Methods yang diekspos melalui penanganan imperatif tidak harus sesuai dengan DOM methods secara persis. Sebagai contoh, komponen Post
berikut mengekspos sebuah method scrollAndFocusAddComment
melalui penanganan imperatif. Hal ini memungkinkan induk Page
menggulir (scroll) daftar komentar dan memfokuskan bidang input ketika Anda mengklik tombol:
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} /> </> ); }