Tìm hiểu và sử dụng React Portal trong NextJs

Trong bài viết này chúng ta sẽ đi tìm hiểu về Portal trong NextJs, đây là một API khá xa lạ và ít được sử dụng nhưng một khi đã tìm hiểu và áp dụng nó vào dự án, bạn sẽ thấy Portal khá hay và rất hữu ích trong nhiều trường hợp.

Vậy Portal là gì, theo document của ReactPortal cho phép chúng ta render một phần HTML đôc lập với commponent tree.

Ta sẽ đi vào ví dụ để hiểu rõ ràng hơn:

Đầu tiên ta sẽ tạo ra một component Portal.tsx

//Portal.tsx
import { useEffect, useState } from "react"
import { createPortal } from "react-dom"

const Portal = ({ children, elementId }) => {
   const [mounted, setMounted] = useState(false)

   useEffect(() => {
      setMounted(true)
      return () => setMounted(false)
   }, [])

   return mounted
      ? createPortal(children, 
        document.querySelector(`#${elementId}`))
      : null
}

export default Portal

Trong component này có hàm createPortal(child, container) với 2 tham số đầu vào là childcontainer, trong đó child là phần tử HTML bạn muốn render có thể là 1 element, string hoặc fragment và container là phần tử DOM element mà bạn muốn phần tử child là con của nó (nó ở đây là container). Ta sẽ truyền vào component 2 props: children elementId (id của thành phần cha muốn render children vào).

Ta có thêm một component TestPortal.tsx.

Như vậy ta có thể thấy 2 props được truyền vào component Portal đó là:

  • children: thành phần HTML <h1>Hello Ecomobi</h1>
  • elementId: “test-portal-id”
//TestPortal.tsx
import Portal from "./Portal";

function TestPortal() {
  return (
    <Portal elementId="test-portal-id">
      <h1>Hello Ecomobi</h1>
    </Portal>
  );
}

export default TestPortal;

Và trong component Home/index.tsx

//Home/index.tsx
import TestPortal from "./components/TestPortal";

export default function Home() {
  return (
    <>
      <div id="container">
        <div id="children-1">
          <div id="children-2">
            <TestPortal />
          </div>
        </div>
      </div>
      <div id="test-portal-id"></div>
    </>
  );
}

Khi đó ta sẽ được kết quả hiển thị trong DOM như thế này:

Có thể thấy mặc dù ta đã đặt component TestPortal vào là con của thành phần divid là “children-2” nhưng hiển thị trên DOM nó lại là con của thành phần div id là “test-portal-id”.

Với việc hoạt động như này thì ta có thể ứng dụng Portal vào để tạo ra các componentstyle 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, Tooltip,… Hoặc chỉ đơn giản ta muốn đưa một component hiển thị đến một vị trí bất kì nào mà ta muốn trong DOM. Cũng tùy vào trường hợp bạn muốn sử dụng Portal như nào.

Trên đây mình đã giới thiệu về React Portal – một API hay gặp nhưng ít được để ý khi phát triển ứng dụng React cũng như trong NextJs. Bài viết có tham khảo từ document chính thức của React, hi vọng bài viết sẽ hữu ích.

Related Posts

1 Comment

Leave a Reply

Your email address will not be published. Required fields are marked *