Trong phát triển React hiện đại, chúng ta thường tìm kiếm cách để quản lý logic của component một cách tinh gọn mà không làm lộ các phần nội bộ không cần thiết. Một công cụ mạnh mẽ trong kho vũ khí nâng cao của React chính là hook useImperativeHandle. Hook này cho phép các component dạng hàm cung cấp các phương thức kiểu mệnh lệnh cho component cha.
Trong bài viết này, chúng ta sẽ phân tích hook này từng bước, thông qua một ví dụ thực tế được lấy cảm hứng từ logic giao diện tương tác: một component input tùy chỉnh cung cấp phương thức .focus() cho component cha. Bạn sẽ hiểu rõ không chỉ hook này làm gì, mà còn hiểu vì sao, khi nào và cách sử dụng nó như một chuyên gia React thực thụ.
useImperativeHandle
là gì?
useImperativeHandle
là một React hook cho phép bạn tùy biến giá trị được trả về khi sử dụng ref
trên một component. Hook này được sử dụng cùng với forwardRef
.
const MyComponent = forwardRef((props, ref) => { useImperativeHandle(ref, () => ({ customMethod: () => { console.log('Custom method called!'); } })); return <div>Hello</div>;
});
Điều này cho phép component cha gọi trực tiếp customMethod()
thông qua ref
.
Vì sao nên sử dụng?
Mặc định, ref
trả về DOM node gốc. Nhưng nếu bạn muốn cung cấp các chức năng cụ thể? useImperativeHandle
cho bạn quyền kiểm soát chính xác những gì được cung cấp ra ngoài, giúp giữ cho phần cài đặt bên trong của component được đóng gói.
Trường hợp sử dụng
- Gọi các phương thức
focus
,blur
hoặcscroll
trên component input tùy chỉnh - Điều khiển animation hoặc transition từ component cha
- Gọi phương thức
reset
hoặcsubmit
trong các component biểu mẫu
Ví dụ thực tế: Custom Input với phương thức Focus
Hãy xây dựng một component TextInput
có thể tái sử dụng, cho phép component cha gọi .focus()
một cách chương trình hóa.
1. Tạo Component
import React, { useRef, useImperativeHandle, forwardRef } from 'react'; interface TextInputHandle { focus: () => void;
} const TextInput = forwardRef<TextInputHandle>((props, ref) => { const inputRef = useRef<HTMLInputElement>(null); useImperativeHandle(ref, () => ({ focus() { inputRef.current?.focus(); } })); return <input ref={inputRef} type="text" className="custom-input" />;
});
2. Sử dụng trong Component Cha
export const App = () => { const inputRef = useRef<TextInputHandle>(null); return ( <div> <h3>Imperative Handle Demo</h3> <TextInput ref={inputRef} /> <button onClick={() => inputRef.current?.focus()}> Focus Input </button> </div> );
};
Khi bạn nhấn nút, TextInput
sẽ được focus.
Các khái niệm chính
Thử thách nâng cao
Hãy mở rộng TextInput để bao gồm:
- Phương thức
.clear()
để xóa nội dung input - Phương thức
.getValue()
để trả về giá trị hiện tại
Ví dụ:
useImperativeHandle(ref, () => ({ focus: () => inputRef.current?.focus(), clear: () => inputRef.current && (inputRef.current.value = ''), getValue: () => inputRef.current?.value
}));
Kết luận
Hook useImperativeHandle
là một kỹ thuật nâng cao nhưng rất mạnh mẽ trong React. Nó mang đến cho bạn khả năng kiểm soát chi tiết việc tương tác giữa các component, cho phép bạn cung cấp các API sạch sẽ, dễ tái sử dụng mà không ảnh hưởng đến tính đóng gói.
Hiểu và thành thạo useImperativeHandle
là một bước quan trọng để trở thành chuyên gia React thực thụ.