Khi chúng ta tạo các thành phần trong React, thông thường chúng tồn tại trong cây thành phần. Điều này hầu hết đều ổn, nhưng đôi khi chúng ta muốn các phần nhất định của một thành phần xuất hiện bên ngoài cây thành phần hoặc ở một nơi nào đó hoàn toàn khác.
Đây là một yêu cầu phổ biến khi chúng tôi tạo các cửa sổ bật lên theo phương thức, cần phải nằm trên tất cả các thành phần khác.
Chúng tôi có thể tạo những thứ này trong một thành phần, nhưng cuối cùng chúng tôi sẽ muốn chúng ở trên mọi thứ khác và việc chúng được lồng trong nhiều thành phần có thể gây ra sự cố vì z-index
của chúng sẽ giảm xuống dưới bất kỳ thứ gì chúng có trong:
Để giải quyết vấn đề này, chúng ta có thể dịch chuyển phương thức ra khỏi thành phần của chính nó và vào một phần khác của mẫu bằng cách sử dụng createPortal
.
Điều này cho phép chúng tôi đặt thành phần của mình ở bất kỳ nơi nào khác mà chúng tôi mong muốn, chẳng hạn như cơ sở của cây HTML, bên trong thẻ body
hoặc bên trong một phần tử khác.
Mặc dù phần tử tồn tại trong cây thành phần, createPortal
cung cấp cho chúng ta sức mạnh để đặt nó ở bất cứ đâu chúng ta muốn.
Để cho bạn thấy các cổng hoạt động như thế nào, hãy xem chúng tôi có mã React cơ bản sau bên trong tệp App.js
của chúng tôi. Ở đây, chúng tôi muốn phương thức xuất hiện trên mọi thứ khác. Như vậy, chúng tôi đã tạo một div
có tên là #modal-container
. Đây cuối cùng là nơi chúng tôi muốn tất cả các phương thức của mình đi vào:
import logo from './logo.svg'; import './App.css'; import { useState } from 'react' import Modal from './components/Modal.js'; function App() { const [isModalOpen, setIsModalOpen] = useState(false); return ( <div className="App"> <header className="App-header"> <img src={logo} className="App-logo" alt="logo" /> <p> Edit <code>src/App.js</code> and save to reload. </p> <button onClick={() => setIsModalOpen(!isModalOpen)}> Click to Open Modal </button> <Modal modalState={isModalOpen} onClickEvent={() => setIsModalOpen(!isModalOpen)}> This is Modal Content! </Modal> </header> <div id="modal-container"></div> </div> ); } export default App;
Bên trong App.js
, tôi đã nhập một thành phần có tên là Modal
. Đây là thành phần Phương thức của chúng tôi, sẽ bật lên bất cứ khi nào người dùng nhấp vào nút.
Bất cứ khi nào isModalOpen
được đặt thành true bằng cách sử dụng setIsModalOpen()
, phương thức sẽ xuất hiện. Nếu không, nó sẽ biến mất.
Tôi cũng có một chút CSS để đảm bảo các phương thức của chúng tôi thực sự xuất hiện trên mọi thứ khác:
#modal-container { position: absolute; top: 0; left: 0; width: 100%; z-index: 9999; height: 100%; pointer-events: none; } .modal { position: absolute; top: 200px; background: white; border-radius: 4px; left: calc(50% - 100px); width: 200px; }
Tạo một cổng thông tin khá dễ dàng - có một chức năng, createPortal()
. Thay vì trả lại một số DOM trong React, chúng tôi trả lại Portal
thay thế.
createPortal()
chấp nhận hai đối số - phần tử DOM mà chúng tôi muốn trả về - trong trường hợp này là phương thức - và phần tử DOM mà chúng tôi muốn dịch chuyển phần tử DOM của mình đến.
Vì vậy, đối số thứ hai của chúng tôi là document.getElementById('modal-container')
, vì chúng tôi muốn đặt tất cả các phương thức của mình vào #modal-container
:
import { createPortal } from 'react-dom'; function Modal({modalState, onClickEvent}) { if(!modalState) return null; return ( createPortal( <div className="modal"> <button onClick={onClickEvent}>Close Modal</button> <div className="modal-content">Modal Content goes here</div> </div>, document.getElementById('modal-container') ) ); }; export default Modal;
Mặc dù chúng tôi đã dịch chuyển phần tử DOM của mình đến modal-container
, nhưng nó vẫn hoạt động như một React con bình thường. Vì Cổng thông tin vẫn tồn tại trong cây React, các tính năng như ngữ cảnh mà phần tử đang sử dụng vẫn hoạt động như cũ.
Cũng cần lưu ý rằng mặc dù chúng ta có modal-container
và Modal
trong cùng một tệp, nhưng nơi bạn dịch chuyển phần tử DOM của mình đến có thể ở bất kỳ đâu trong mã React của bạn.
Vì vậy, bạn có thể dịch chuyển nó đến một thành phần con, phần tử hoặc cha hoàn toàn khác ở bất kỳ đâu trong DOM. Nó khá mạnh mẽ và hữu ích - vì vậy hãy sử dụng nó một cách khôn ngoan.
Hãy nhìn lại HTML App.js
của chúng tôi:
<!-- .... --> <button onClick={() => setIsModalOpen(!isModalOpen)}> Click to Open Modal </button> <Modal modalState={isModalOpen} onClickEvent={() => setIsModalOpen(!isModalOpen)}> This is Modal Content! </Modal> </header> <div id="modal-container"></div>
Bây giờ, mặc dù Modal
nằm trong tiêu đề của chúng ta, nó sẽ xuất hiện trong #modal-container
bất cứ khi nào chúng ta mở phương thức bằng cách sử dụng nút:
Cổng là một công cụ khá mạnh trong React. Chúng là một cách hữu ích để giải quyết vấn đề chính với các hệ thống dựa trên thành phần - vận chuyển các yếu tố nhất định lên trên tất cả các yếu tố còn lại.
Vì vậy, tôi hy vọng bạn thích hướng dẫn về cổng React này. Nếu bạn đang học React, trước tiên tôi khuyên bạn nên thành thạo Javascript - điều này bạn có thể làm với Sổ tay Javascript đầy đủ của tôi.
Có một ngày tuyệt vời.