Hiểu Biết Về Delegation Sự Kiện Trong React: Trước & Sau
Khi chúng ta xây dựng ứng dụng web, việc xử lý các tương tác của người dùng (như nhấn chuột, nhấn phím hoặc gửi biểu mẫu) là một phần rất quan trọng trong công việc. Tuy nhiên, cách mà chúng ta xử lý những sự kiện này đã thay đổi rất nhiều qua các năm. Một trong những cải tiến quan trọng là điều được gọi là delegation sự kiện.
Hãy cùng tìm hiểu khái niệm này từng bước — bắt đầu từ cách mà chúng ta đã làm trước khi có delegation, và cách mà React đã cải thiện điều đó.
📍 Trước Khi Có Delegation Sự Kiện: Gắn Sự Kiện Trực Tiếp
Trong những ngày đầu của JavaScript, nếu bạn muốn làm cho nhiều nút phản hồi khi nhấn chuột, cách đơn giản là gắn một listener sự kiện trực tiếp vào từng nút.
Ví dụ:
javascript
const buttons = document.querySelectorAll('button');
buttons.forEach(button => {
button.addEventListener('click', () => {
console.log('Button clicked!');
});
});
👉 Điều này có nghĩa:
- Mỗi phần tử sẽ có một listener sự kiện riêng.
- Nếu bạn có 1.000 nút, bạn sẽ kết thúc với 1.000 listener trong bộ nhớ.
⚠️ Vấn đề với phương pháp cũ:
- Vấn đề hiệu suất: Quá nhiều listener làm chậm trang web.
- Tải bộ nhớ: Mỗi listener chiếm không gian bộ nhớ.
- Khó khăn trong bảo trì: Nếu bạn xóa một phần tử, bạn cũng cần xóa listener của nó.
- Quirk giữa các trình duyệt: Các trình duyệt khác nhau xử lý sự kiện khác nhau.
📍 Sự Xuất Hiện Của Delegation Sự Kiện
Lúc này, delegation sự kiện xuất hiện. Thay vì gắn listener cho từng phần tử, bạn gắn một listener cho một phần tử cha (hoặc thậm chí là tài liệu).
Điều này hoạt động nhờ vào sự nổi bọt của sự kiện:
Khi bạn nhấn vào một phần tử con, sự kiện sẽ di chuyển (hoặc "nổi bọt lên") qua các tổ tiên của nó cho đến khi nó đến gốc.
Phần tử cha có thể "bắt" sự kiện đó và xác định phần tử con nào đã kích hoạt nó.
Ví dụ:
javascript
const parent = document.getElementById('parent');
parent.addEventListener('click', (event) => {
if (event.target.tagName === 'BUTTON') {
console.log('Button clicked!');
}
});
👉 Điều gì đã thay đổi:
Một listener sự kiện duy nhất trên phần tử cha xử lý tất cả các lần nhấn nút con.
Việc thêm hoặc xóa nút không yêu cầu gắn hoặc xóa listener mới.
✅ Cải tiến:
- Hiệu suất tốt hơn.
- Sử dụng bộ nhớ ít hơn.
- Cập nhật DOM dễ dàng hơn.
📍 Cách Tiếp Cận Của React: Sự Kiện Tổng Hợp + Delegation
React đã nâng cao ý tưởng này hơn nữa. Khi bạn viết:
javascript
<button onClick={handleClick}>Click me</button>
…trông như bạn đang gắn một listener trực tiếp vào nút. Nhưng thực tế, React không gắn một listener lên mỗi nút.
🔧 Điều gì mà React làm thay vào đó:
- React gắn một listener duy nhất (theo loại sự kiện, như nhấn chuột) ở cấp độ gốc.
- Khi một sự kiện DOM thực sự xảy ra, React sẽ chặn nó.
- React tạo ra một
SyntheticEvent— một lớp bọc chuẩn hóa sự khác biệt giữa các trình duyệt (để bạn không cần lo lắng về những bất đồng nhưevent.targetvàevent.srcElement). - React phát tán sự kiện bên trong đến handler
onClickcủa component đúng.
🚀 Những Suy Nghĩ Cuối Cùng
Delegation sự kiện đã biến đổi cách mà chúng ta xử lý các tương tác của người dùng. Thay vì làm rối mỗi phần tử với một listener riêng, chúng ta hiện nay dựa vào việc nổi bọt và các listener tập trung.
React đã tăng cường điều này bằng cách giới thiệu hệ thống Sự Kiện Tổng Hợp của nó, làm cho việc xử lý sự kiện:
- Nhanh hơn
- An toàn hơn giữa các trình duyệt
- Dễ bảo trì hơn
Vì vậy, lần tới khi bạn viết một onClick trong React, hãy nhớ — nó không được gắn trực tiếp vào nút của bạn. React đang lặng lẽ xử lý nó cho bạn thông qua delegation.
Thực Hành Tốt Nhất
- Sử dụng sự kiện tổng hợp của React: Điều này giúp đồng nhất cách xử lý sự kiện trên các trình duyệt khác nhau.
- Tránh gắn listener trực tiếp: Sử dụng delegation để tăng cường hiệu suất.
- Kiểm tra hiệu suất: Sử dụng công cụ như Chrome DevTools để theo dõi hiệu suất của các sự kiện.
Cạm Bẫy Thường Gặp
- Quên kiểm tra
event.target: Hãy chắc chắn bạn đang kiểm tra đúng phần tử. - Không xử lý sự kiện ở cấp cha: Có thể dẫn đến việc không bắt được sự kiện.
Mẹo Hiệu Suất
- Hạn chế số lượng sự kiện gắn vào DOM.
- Sử dụng các phương pháp tối ưu hóa như
requestAnimationFramecho các sự kiện có hiệu ứng.
Giải Quyết Vấn Đề
- Nếu sự kiện không được kích hoạt, hãy kiểm tra các phần tử cha để xác minh rằng listener đã được gắn đúng cách.
Câu Hỏi Thường Gặp
1. Delegation sự kiện là gì?
Delegation sự kiện là kỹ thuật gắn một listener sự kiện vào một phần tử cha thay vì từng phần tử con.
2. Tại sao tôi nên sử dụng delegation sự kiện?
Nó giúp cải thiện hiệu suất và giảm việc sử dụng bộ nhớ trong ứng dụng web của bạn.
3. React có hỗ trợ delegation sự kiện không?
Có, React sử dụng một hệ thống sự kiện tổng hợp, cho phép xử lý sự kiện hiệu quả hơn.
Kết Luận
Delegation sự kiện là một kỹ thuật mạnh mẽ giúp tăng cường hiệu suất và tính khả dụng của ứng dụng web. Bằng cách sử dụng các listener tập trung và sự kiện tổng hợp của React, bạn có thể xây dựng các ứng dụng dễ bảo trì và hiệu suất cao hơn. Hãy bắt đầu áp dụng những kiến thức này vào dự án của bạn ngay hôm nay!