2017-09-24 20 views
10

Tôi đang sử dụng React 16 và cần cổng, nhưng không thể tìm thấy bất kỳ tài liệu nào về tính năng này. Có ai biết cách sử dụng cái này chưa?Làm thế nào để sử dụng ReactDOM.createPortal() trong React 16?

https://github.com/facebook/react/pull/10675

Cảm ơn lời khuyên nào.

+1

https://facebook.github.io/react/docs/portals.html –

+1

Tài liệu giải thích rõ ràng cách sử dụng chúng ... bạn đã đọc chúng chưa? – ndugger

+0

@ndugger Vâng, Tài liệu đủ tốt ngay bây giờ :). Nhưng OP đã hỏi câu hỏi 2 ngày trước. React v16 đã không được phát hành sau đó. Nó đã được phát hành ngày hôm nay và các tài liệu cũng đã có sẵn ngày hôm nay. –

Trả lời

14

React v16 vừa mới phát hành một vài giờ trước (Yay !!), chính thức hỗ trợ Portal.

Cổng là gì? Vì nó đã ở đó bao lâu?

Cổng cung cấp cách thứ nhất để đưa trẻ em vào nút DOM tồn tại bên ngoài phân cấp DOM của thành phần gốc.

Portal không phải là khái niệm mới trong cộng đồng phản ứng. Nhiều thư viện có sẵn hỗ trợ loại chức năng này. ví dụ: react-portalreact-gateway.

Điều gì sẽ xảy ra khi hiển thị bất kỳ ứng dụng phản ứng nào?

Nói chung, khi hiển thị bất kỳ ứng dụng React nào, một phần tử DOM duy nhất được sử dụng để hiển thị toàn bộ cây React.

class HelloReact extends React.Component { 
    render() { 
     return (
      <h1>Hello React</h1> 
     ); 
    } 
} 

ReactDOM.render(<HelloReact />, document.getElementById('root')); 

Như bạn có thể thấy chúng tôi đang hiển thị thành phần phản ứng của chúng tôi thành phần tử DOM có id root.

Cổng là gì và tại sao lại cần thiết? Tại sao nó lại ở đó?

Portals là một cách để làm cho trẻ em Phản ứng bên ngoài hệ thống phân cấp DOM chính của thành phần cha mẹ mà không làm mất phản ứng bối cảnh. Tôi đang nhấn mạnh vào nó bởi vì các thư viện rất phổ biến như react-router, redux sử dụng nhiều bối cảnh phản ứng. Vì vậy, tính khả dụng của ngữ cảnh khi sử dụng Portal rất hữu ích.

Theo react docs,

Một trường hợp sử dụng điển hình cho các cổng thông tin là khi một thành phần cha mẹ có overflow: hidden hoặc z-index phong cách, nhưng bạn cần đứa trẻ để trực quan "bùng nổ" của container của nó. Ví dụ: hộp thoại, thẻ di chuột và chú giải công cụ.

Vì vậy, với cổng, bạn có thể hiển thị cây phản ứng song song trên nút DOM khác khi cần. Mặc dù nó được hiển thị trong nút DOM khác nhau, thành phần cha mẹ có thể nắm bắt các sự kiện chưa được nắm bắt. Xem số này codepen được cung cấp trong chính tài liệu.

Ví dụ dưới đây sẽ cung cấp cho ý tưởng hơn của bạn:

// index.html 
<html> 
    <body> 
     <div id="root"></div> 
     <div id="another-root"></div> 
    </body> 
</html> 

// index.jsx 
const mainContainer = document.getElementById('root'); 
const portalContainer = document.getElementById('another-root'); 

class HelloFromPortal extends React.Component { 
    render() { 
     return (
      <h1>I am rendered through a Portal.</h1> 
     ); 
    } 
} 

class HelloReact extends React.Component { 
    render() { 
     return (
      <div> 
       <h1>Hello World</h1> 
       { ReactDOM.createPortal(<HelloFromPortal />, portalContainer) } 
      </div> 
     ); 
    } 
} 

ReactDOM.render(<HelloReact />, mainContainer); 

https://codesandbox.io/s/62rvxkonnw

Bạn có thể sử dụng DevTools kiểm tra nguyên tố và thấy rằng <h1>I am rendered through a Portal.</h1> được render bên #another-root thẻ, trong khi <h1>Hello World</h1> được render bên #root thẻ.

Hope this helps :)

Cập nhật: Để trả lời câu @PhillipMunin's comment.

Sự khác nhau giữa ReactDOM.renderReactDOM.createPortal là gì?

  1. Mặc dù các thành phần được cung cấp đến các cổng được trả lại ở một nơi khác (ngoài các gốc chứa hiện hành), nó vẫn còn hiện diện như là con của cùng một thành phần cha mẹ. (Ai đã gọi số ReactDOM.createPortal) Vì vậy, bất kỳ sự kiện nào trên trẻ được truyền cho phụ huynh. (Ofc, Tính năng này không hoạt động nếu bạn dừng phát tán sự kiện theo cách thủ công.)

  2. Có thể truy cập bối cảnh tương tự trong thành phần được hiển thị thông qua cổng. Nhưng không phải trong trường hợp chúng tôi thực hiện trực tiếp ReactDOM.render.

Tôi đã tạo một bản trình diễn khác để minh họa quan điểm của tôi. https://codesandbox.io/s/42x771ykwx

+2

Điều này khác với cách nào khi viết '{ReactDOM.render (, portalContainer)}' thay vì '{ReactDOM.createPortal (...)}'? Tôi đã thử nghiệm nó trong codesandbox - dường như không có bất kỳ khác nhau: https://codesandbox.io/s/88p7lwn3l –

+0

@PhilippMunin Ngoài ngữ cảnh được lưu trong các cổng, các sự kiện được truyền bá. Hãy thử thêm một trình nghe nhấp chuột vào div trên cùng của '' và thấy rằng khi sử dụng 'render' nhấp chuột từ' 'không truyền lên. Khi sử dụng 'createPortal', các nhấp chuột từ bên trong cổng thông tin sẽ lan truyền đến thành phần cha. – lyosef

+0

Còn ReactDOM.unstable_renderSubtreeIntoContainer thay vì render thì sao? nó phải vượt qua bối cảnh, không chắc chắn về sự kiện –

0

Cổng thông tin được tạo bằng cách gọi phương thức createPortal bên trong phương thức render của thành phần của bạn.

render() { 
    return (
    <div> 
     {ReactDOM.createPortal(this.renderPortal(), this.props.portalEl)} 
    </div> 
) 
} 

renderPortal nên trả lại nội dung cần trả lại bên trong cổng thông tin, trong khi portalEl là một phần tử DOM bên ngoài mà sẽ nhận được nội dung.

Ai đó gần đây đã thu gọn thông tin đó trên cổng có thể được tìm thấy trong React tests.

Các vấn đề liên quan