useImperativeHandle
useImperativeHandle
là một React Hook cho phép bạn tùy chỉnh handle được hiển thị dưới dạng một ref.
useImperativeHandle(ref, createHandle, dependencies?)
Tham khảo
useImperativeHandle(ref, createHandle, dependencies?)
Gọi useImperativeHandle
ở cấp cao nhất của component để tùy chỉnh ref handle mà nó hiển thị:
import { useImperativeHandle } from 'react';
function MyInput({ ref }) {
useImperativeHandle(ref, () => {
return {
// ... các phương thức của bạn ...
};
}, []);
// ...
Tham số
-
ref
:ref
bạn nhận được như một prop cho componentMyInput
. -
createHandle
: Một hàm không nhận đối số và trả về ref handle bạn muốn hiển thị. Ref handle đó có thể có bất kỳ kiểu nào. Thông thường, bạn sẽ trả về một object với các phương thức bạn muốn hiển thị. -
optional
dependencies
: Danh sách tất cả các giá trị reactive được tham chiếu bên trong codecreateHandle
. Các giá trị reactive bao gồm props, state và tất cả các biến và hàm được khai báo trực tiếp bên trong phần thân component của bạn. Nếu linter của bạn được cấu hình cho React, nó sẽ xác minh rằng mọi giá trị reactive được chỉ định chính xác như một dependency. Danh sách các dependency phải có một số lượng mục không đổi và được viết nội dòng như[dep1, dep2, dep3]
. React sẽ so sánh từng dependency với giá trị trước đó của nó bằng cách sử dụng so sánhObject.is
. Nếu việc render lại dẫn đến thay đổi đối với một số dependency hoặc nếu bạn bỏ qua đối số này, hàmcreateHandle
của bạn sẽ thực thi lại và handle mới được tạo sẽ được gán cho ref.
Returns
useImperativeHandle
trả về undefined
.
Cách sử dụng
Hiển thị một ref handle tùy chỉnh cho component cha
Để hiển thị một DOM node cho phần tử cha, hãy truyền prop ref
vào node đó.
function MyInput({ ref }) {
return <input ref={ref} />;
};
Với đoạn code trên, một ref đến MyInput
sẽ nhận được DOM node <input>
. Tuy nhiên, bạn có thể hiển thị một giá trị tùy chỉnh thay thế. Để tùy chỉnh handle được hiển thị, hãy gọi useImperativeHandle
ở cấp cao nhất của component:
import { useImperativeHandle } from 'react';
function MyInput({ ref }) {
useImperativeHandle(ref, () => {
return {
// ... các phương thức của bạn ...
};
}, []);
return <input />;
};
Lưu ý rằng trong đoạn code trên, ref
không còn được truyền cho <input>
.
Ví dụ: giả sử bạn không muốn hiển thị toàn bộ DOM node <input>
, nhưng bạn muốn hiển thị hai trong số các phương thức của nó: focus
và scrollIntoView
. Để thực hiện việc này, hãy giữ DOM trình duyệt thực trong một ref riêng biệt. Sau đó, sử dụng useImperativeHandle
để hiển thị một handle chỉ với các phương thức mà bạn muốn component cha gọi:
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} />;
};
Bây giờ, nếu component cha nhận được một ref đến MyInput
, nó sẽ có thể gọi các phương thức focus
và scrollIntoView
trên đó. Tuy nhiên, nó sẽ không có toàn quyền truy cập vào DOM node <input>
cơ bản.
import { useRef } from 'react'; import MyInput from './MyInput.js'; export default function Form() { const ref = useRef(null); function handleClick() { ref.current.focus(); // Thao tác này sẽ không hoạt động vì DOM node không được hiển thị: // ref.current.style.opacity = 0.5; } return ( <form> <MyInput placeholder="Nhập tên của bạn" ref={ref} /> <button type="button" onClick={handleClick}> Chỉnh sửa </button> </form> ); }
Hiển thị các phương thức imperative của riêng bạn
Các phương thức bạn hiển thị thông qua một imperative handle không nhất thiết phải khớp chính xác với các phương thức DOM. Ví dụ: component Post
này hiển thị một phương thức scrollAndFocusAddComment
thông qua một imperative handle. Điều này cho phép Page
cha cuộn danh sách các comment và focus vào trường input khi bạn nhấp vào nút:
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}> Viết một bình luận </button> <Post ref={postRef} /> </> ); }