useImperativeHandle diperkenalkan di React 16.8 (Februari 2019) — versi yang sama ketika React pertama kali memperkenalkan Hooks seperti useState, useEffect, dan useRef.
Pola Umum: Parent → Props → Child
Dalam React, aliran data biasanya mengalir dari parent ke child lewat props.
Misalnya, kalau parent ingin memicu re-render pada child, ia cukup mengubah props yang dikirim.
Pola ini bersih, bisa diprediksi, dan menjaga setiap komponen tetap terisolasi.
Tapi, kadang kita butuh arah sebaliknya.
Bayangkan kamu punya sebuah komponen <Modal>, dan parent ingin membuka atau menutup modal tersebut secara imperatif — bukan dengan mengubah props, tapi dengan memanggil sebuah method langsung:
modalRef.current.open()Di sinilah useImperativeHandle berperan.
Peran useImperativeHandle
useImperativeHandle adalah React Hook yang memungkinkan kita untuk mengatur apa yang terekspos lewat ref pada komponen child.
Hook ini selalu digunakan bersama dengan forwardRef.
Contoh dasarnya seperti ini:
useImperativeHandle(ref, () => ({
methodYouExpose() {
// some logic here
}
}));Sebelum ada React Hooks, developer banyak bergantung pada class component dan sistem ref untuk membuat perilaku imperatif.
Mari lihat perbandingannya.
Cara Lama (Sebelum Hooks Ada)
Di class component, membuat method imperatif yang bisa diakses dari parent sangat mudah — cukup definisikan method publik di dalam class, lalu akses lewat ref:
<reactpack
options="{
'editorHeight': '500px'
}"
>
```js /Modal.js active
// Modal.js (class-based)
import React from "react";
class Modal extends React.Component {
state = { isOpen: false };
open() {
this.setState({ isOpen: true });
}
close() {
this.setState({ isOpen: false });
}
render() {
if (!this.state.isOpen) return null;
return (
<div className="modal">
<div className="modal-content">
{this.props.children}
<button onClick={() => this.close()}>Close</button>
</div>
</div>
);
}
}
export default Modal;
```
```js /App.js
import React, { Component, createRef } from "react";
import Modal from "./Modal";
class App extends Component {
// The parent component could control it directly using a ref:
modalRef = createRef();
render() {
return (
<div>
<button onClick={() => this.modalRef.current.open()}>Open Modal</button>
<Modal ref={this.modalRef}>
<h2>Hello from the modal!</h2>
</Modal>
</div>
);
}
}
export default App;
```
</reactpack>Pendekatan ini sangat natural di era class component.
Namun ketika React beralih ke function component + Hooks, pendekatan ini tidak lagi bisa dilakukan langsung — karena function component tidak punya instance seperti class.
Itulah alasan kenapa useImperativeHandle diperkenalkan.
Cara Modern: useImperativeHandle dengan Hooks
useImperativeHandle memungkinkan function component untuk mengekspos method imperatif secara terbatas ke parent lewat ref, mirip seperti perilaku instance pada class.
Mari kita tulis ulang contoh modal sebelumnya menggunakan Hooks:
<reactpack
options="{
'editorHeight': '500px'
}"
>
```js /Modal.js active
import React, { useState, useImperativeHandle, forwardRef } from "react";
const Modal = forwardRef((props, ref) => {
const [isOpen, setIsOpen] = useState(false);
useImperativeHandle(ref, () => ({
open() {
setIsOpen(true);
},
close() {
setIsOpen(false);
}
}));
if (!isOpen) return null;
return (
<div className="modal">
<div className="modal-content">
{props.children}
<button onClick={() => setIsOpen(false)}>Close</button>
</div>
</div>
);
});
export default Modal;
```
```js /App.js
import React, { useRef } from "react";
import Modal from "./Modal";
function App() {
const modalRef = useRef();
return (
<div>
<button onClick={() => modalRef.current.open()}>Open Modal</button>
<Modal ref={modalRef}>
<h2>Hello from the modal!</h2>
</Modal>
</div>
);
}
export default App;
```
</reactpack>Sekarang, parent tetap bisa memanggil modalRef.current.open() atau modalRef.current.close(),
sama seperti di class component — tapi dengan gaya functional yang modern.
Kenapa Tidak Cukup Gunakan Props?
Pertanyaan yang bagus:
“Bukankah kita bisa pakai isOpen prop saja dan atur secara deklaratif?”
Jawabannya: bisa, dan itu seharusnya jadi pendekatan utama.
Pendekatan deklaratif membuat alur data lebih mudah diprediksi dan mudah di-debug.
Namun ada beberapa kasus di mana pendekatan imperatif lebih masuk akal:
- Saat integrasi dengan kode non-React (misalnya library chart, map, atau video player).
- Ketika child punya state internal kompleks yang tidak perlu diketahui parent.
- Saat kamu ingin mengekspose utilitas tertentu seperti
focus(),scrollToTop(), ataureset().
useImperativeHandle memungkinkan kamu menyediakan API terbatas dan terkontrol untuk situasi seperti ini.
Cara Kerjanya di Balik Layar
forwardRefmengirim ref dari parent ke child.useImperativeHandlememberitahu React apa nilai yang seharusnya diwakili oleh ref.current di parent.
Contoh:
useImperativeHandle(ref, () => ({
open: () => setIsOpen(true),
close: () => setIsOpen(false)
}));Dengan begitu, ref.current di parent akan berisi objek dengan dua method: open dan close.
Tanpa useImperativeHandle, ref pada function component hanya akan menunjuk ke DOM node atau null.
Kapan Sebaiknya Dihindari
useImperativeHandle memang powerful, tapi bisa membuat komponen jadi lebih sulit diuji dan dipahami.
Kalau kamu sering menggunakannya, itu bisa jadi sinyal bahwa desain komponenmu terlalu rapat (tightly coupled).
Gunakan props secara deklaratif sebisa mungkin,
dan simpan useImperativeHandle untuk kasus-kasus spesifik di mana memang benar-benar dibutuhkan.
Apa yang Saya Pelajari
Ketika pertama kali belajar useImperativeHandle, saya pikir hook ini hanyalah workaround — semacam “jalan belakang” untuk mengontrol child dari parent.
Tapi lama-lama saya sadar: hook ini sebenarnya jembatan yang rapi antara logika deklaratif dan imperatif.
Bukan untuk melanggar filosofi React, tapi untuk memperluasnya dengan cara yang terukur dan aman.
Hal Penting yang Perlu Diingat
- Versi React: tersedia sejak React 16.8 (2019)
- Tujuan: menyesuaikan nilai yang terekspos oleh
refke parent - Kapan digunakan: integrasi pihak ketiga, logika UI kompleks, atau method utilitas tertentu
- Best practice: tetap utamakan pendekatan deklaratif — gunakan
useImperativeHandlehanya bila benar-benar perlu
Penutup
Salah satu kekuatan terbesar React adalah sifatnya yang deklaratif,
tapi dunia nyata tidak selalu bisa 100% deklaratif.
Kadang kamu perlu menangani sesuatu secara imperatif — memfokuskan input, memicu modal, atau mereset form.useImperativeHandle memberi fleksibilitas itu tanpa melanggar batas komponen.
Jika digunakan dengan hati-hati dan bijak,
ini adalah salah satu alat kecil yang bisa membuat komponenmu lebih adaptif dan ekspresif.
Memahami `useImperativeHandle` di `React`
Refleksi dari apa yang saya pelajari saat mengeksplorasi `useImperativeHandle`: apa fungsinya, kapan sebaiknya digunakan, dan bagaimana cara memakainya tanpa melanggar sifat deklaratif React.