Trong bài viết này, mình sẽ giới thiệu về Portal trong ReactJS, một API có thể nghe có vẻ lạ lẫm và ít được sử dụng. Tuy nhiên, mình tin rằng bạn đã từng sử dụng nó trong quá trình phát triển ứng dụng web với React mà có thể chưa nhận ra.
Vậy React Portal là gì?
Portal trong ReactJS là một tính năng cho phép bạn render các thành phần (components) của React ở bên ngoài cây DOM cha của chúng.
Thông thường, các thành phần React được gắn liền với cây DOM nơi chúng được khai báo.
Tuy nhiên, trong một số trường hợp đặc biệt, bạn có thể muốn render một thành phần ở một vị trí khác trong DOM, ví dụ như khi cần đặt một modal, tooltip, hoặc hộp thoại xác nhận ở ngoài phần tử gốc mà vẫn giữ nguyên khả năng quản lý và cập nhật thông qua React.
Portal giải quyết vấn đề này bằng cách tạo ra một “cổng” kết nối giữa cây DOM cha và một điểm khác trong DOM, từ đó cho phép bạn dễ dàng đưa nội dung của một thành phần ra ngoài bối cảnh DOM hiện tại mà không làm mất đi khả năng tương tác hoặc cập nhật.
Ví dụ
Bình thường trong project reactjs ta có file index.html
Và tại app.js ta có:
ReactDOM.render(<App />, document.getElementById('root'))
Toàn bộ ứng dụng sẽ được nằm trong thẻ div với id là root.
Tiếp theo giả sử ta có như sau, bên trong App:
function App() {
return (
<div className="app-wrapper">
<HomePage />
<Footer />
</div>
);
}
Nếu các component đều sử dụng phương thức render thì nội dung trong các child-component là HomePage và Footer sẽ nằm trong thẻ div với class là app-wrapper, tương tự với các level tiếp theo.
Việc render nội dung như vậy nhìn chung rất bình thường, tuy nhiên một số trường hợp ta muốn tạo ra một component, có style không bị ảnh hưởng bởi thành phần parent của nó bất kể level mà nó được render.
Ví dụ như Modal, hay Tooltip chẳng hạn, đối với các component này, thay vì sử dụng phương thức render như thường lệ như sau:
import React from 'react'
function Modal({ children }) {
return (
<div>
{children}
</div>
);
}
export default Modal;
Ta nên sử dụng React Portal như sau:
<html>
<head></head>
<body>
<div id="root"></div>
<div id="modal-wrapper"></div>
</body>
</html>
Vì vậy phần style của modal-wrapper sẽ không bị ảnh hưởng bởi level mà Modal được render bên trong component tree của project, mà chỉ ảnh hưởng bởi global style.
Vui lòng tham khảo thêm tại tài liệu của React Portal để biết kỹ hơn