Trong phần 6 này, chúng ta sẽ tìm hiểu cách sử dụng hook useImperativeHandle
useImperativeHandle
useImperativeHandle là một React Hook cho phép bạn tùy chỉnh phần xử lý được hiển thị dưới dạng ref.
Cách sử dụng
useImperativeHandle(ref, createHandle, dependencies?)
- ref: ở đây là paramater thứ 2 trong forwardRef render function. Thuộc tính
ref
được truyền bởi component cha , nó có thể là object hoặc function - createHandle: Đây là 1 hàm không có đối số và trả về ref handle mà bạn muốn.ref handle có bất kì type nào.Thông thường chúng ta sẽ trả về 1 object với phương thức mà chúng ta mong muốn.
- dependencies: Danh sách tất cả các giá trị sử dụng được tham chiếu bên trong hàm createHandle. Các giá trị đó bao gồm props, state cũng như tất cả các biến và hàm được khai báo trực tiếp bên trong component của bạn.React sẽ so sánh mỗi phụ thuộc với giá trị trước sử dụng “Object.is”.Nếu kết quả render lại không có sự thay đổi hoặc bỏ qua đối số này thì 1 handle mới sẽ được gán cho ref.
Hook này được sử dụng trong các trường hợp:
- Hiển thị xử lý tùy chỉnh ref tới component cha
- Hiển thị các methods riêng bắt buộc
Ví dụ minh họa
Ví dụ 1: Hiển thị xử lý tùy chỉnh ref tới component cha
Theo mặc định, các component không hiển thị các DOM nodes của chúng cho các component cha Ví dụ: nếu bạn muốn component cha của MyInput có quyền truy cập vào DOM nodes <input>
bạn phải chọn tham gia bằng ForwardRef:
import { forwardRef } from 'react';
const MyInput = forwardRef(function MyInput(props, ref) {
return <input {...props} ref={ref} />;
});
Với đoạn mã trên, một tham chiếu tới MyInput sẽ nhận được DOM nodes <input>
Tuy nhiên, thay vào đó, bạn có thể hiển thị một giá trị tùy chỉnh. Để tùy chỉnh xử lý hiển thị, hãy gọi useImperativeHandle ở đầu component của bạn:
import { forwardRef, useImperativeHandle } from 'react';
const MyInput = forwardRef(function MyInput(props, ref) {
useImperativeHandle(ref, () => {
return {
// ... your methods ...
};
}, []);
return <input {...props} />;
});
Lưu ý rằng trong đoạn mã trên, ref không còn được chuyển tiếp đến <input>
nữa.
Ví dụ: giả sử bạn không muốn hiển thị toàn bộ DOM nodes <input>
nhưng bạn muốn hiển thị 2 methods của nó: focus và ScrollIntoView. Để thực hiện việc này, hãy giữ DOM của trình duyệt thực trong một ref riêng. 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 { 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} />;
});
Bây giờ nếu component cha nhận được môt tham chiếu tới MyInput, nó sẽ có thể gọi các method focus và ScrollIntoView trên đó.Tuy nhiên, nó sẽ không có toàn quyền truy cập vào DOM nodes.
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 placeholder="Enter your name" ref={ref} />
<button type="button" onClick={handleClick}>
Edit
</button>
</form>
);
}
Ví dụ 2: Hiển thị các methods riêng bắt buộc
Các phương thức bạn hiển thị thông qua bộ xử lý mệnh lệnh 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ụ: Post component này hiển thị method “ScrollAndFocusAddComment” thông qua một handle bắt buộc. Điều này cho phép trang cha scroll(cuộn) danh sách nhận xét và focus vào input field, 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}>
Write a comment
</button>
<Post ref={postRef} />
</>
);
}
Lưu ý:
- Đừng lạm dụng ref. Bạn chỉ nên sử dụng tham chiếu cho các hành vi bắt buộc mà bạn không thể biểu thị dưới dạng props.Ví dụ: cuộn đến một nút, tập trung vào một nút, kích hoạt hoạt ảnh, chọn văn bản, v.v.
- Nếu bạn có thể hiển thị điều gì đó như một props, bạn không nên sử dụng ref. Ví dụ: thay vì hiển thị imperative handle như { open, close } từ Modal component, tốt hơn nên lấy isOpen là props giống như thế này . Hiệu ứng có thể giúp bạn hiển thị những hành vi bắt buộc thông qua props.
Nguồn dịch: (https://react.dev/reference/react)