React portallari


React portallari HTMLni asosiy componentning DOM ierarxiyasidan tashqarida ko‘rsatish usulini taqdim etadi.

Bu, ayniqsa, konteyner tartibidan chiqib ketishi kerak bo‘lgan modallar, maslahatlar va dialoglar kabi componentlar uchun foydalidir.


ULASHISH

React portallari nima?

Portal - bu react-dom paketiga kiritilgan React usuli.

U asosiy componentning DOM ierarxiyasidan tashqarida HTMLni ko‘rsatish uchun ishlatiladi.

Odatda qaytarilgan HTML elementi asosiy componentning bolasi bo‘lib, quyidagicha qaytariladi:

Misol

createPortal metodidan foydalanmasdan:

function myChild() {
  return (
    <div>
      Welcome
    </div>
  );
}

Ammo createPortal usulidan foydalangan holda, HTML asosiy componentning farzandi emas va asosiy componentning DOM ierarxiyasidan tashqarida ko‘rsatiladi:

Misol

createPortal metodi bilan:

import { createPortal } from 'react-dom';

function myChild() {
  return createPortal(
    <div>
      Welcome
    </div>,
    document.body
  );
}

Sintaksis

import { createPortal } from 'react-dom';

createPortal(children, domNode)

Birinchi argument (children) render qilinishi mumkin bo‘lgan istalgan React kontenti, masalan, elementlar, stringlar yoki fragmentlar.

Ikkinchi argument (domNode) portal joylashtirilishi kerak bo‘lgan DOM elementi.


Portal yordamida modal yaratish

React portallari, ayniqsa, konteyner tartibidan chiqib ketishi kerak bo‘lgan modallar, maslahatlar va dialoglar kabi componentlar uchun foydalidir.

Modal asosiy componentning DOM ierarxiyasidan tashqarida ko‘rsatilgan modal componentga misol:

Misol

import { createRoot } from 'react-dom/client';
import { useState } from 'react';
import { createPortal } from 'react-dom';

function Modal({ isOpen, onClose, children }) {
  if (!isOpen) return null;

  return createPortal(
    <div style={{
      position: 'fixed',
      top: 0,
      left: 0,
      right: 0,
      bottom: 0,
      backgroundColor: 'rgba(0, 0, 0, 0.5)',
      display: 'flex',
      alignItems: 'center',
      justifyContent: 'center'
    }}>
      <div style={{
        background: 'white',
        padding: '20px',
        borderRadius: '8px'
      }}>
        {children}
        <button onClick={onClose}>Close</button>
      </div>
    </div>,
    document.body
  );
}

function MyApp() {
  const [isOpen, setIsOpen] = useState(false);

  return (
    <div>
      <h1>My App</h1>
      <button onClick={() => setIsOpen(true)}>
        Open Modal
      </button>

      <Modal isOpen={isOpen} onClose={() => setIsOpen(false)}>
        <h2>Modal Content</h2>
        <p>This content is rendered outside the App component!</p>
      </Modal>
    </div>
  );
}

createRoot(document.getElementById('root')).render(
  <MyApp />
)

Misolni ishga tushirish »

Misol tushuntirildi

Birinchidan, biz kerakli funksiyalarni import qilamiz:

  • createPortal dan react-dom - portal yaratish uchun
  • useState from react - modalning ochiq/yopiq holatini boshqarish uchun

Modal component o‘z mazmunini to‘g‘ridan-to‘g‘ri document.body elementiga ko‘rsatish uchun createPortal dan foydalanadi.



Nima uchun portallardan foydalanish kerak

Portallar ayniqsa quyidagilar uchun foydalidir:

  • Modallar va dialoglar
  • Maslahat
  • Suzuvchi menyular
  • Bildirishnomalar

Har qanday UI elementi, ayniqsa, asosiy componentda:

  • overflow: hidden
  • z-index conflicts
  • Murakkab joylashishni aniqlash talablari

Portallarda ko‘p qirrali hodisalar

Portal kontentni DOM daraxtining boshqa qismida ko‘rsatsa ham, portal tarkibidagi hodisalar portal mavjud bo‘lmagandek React componentlar daraxti orqali ko‘tariladi.

Misol uchun, agar portal ichidagi tugma bosilsa, voqea hali ham asosiy componentga ko‘tariladi va ota-componentning hodisa ishlovchisi ishga tushadi.

Misol

Tugmani ham, asosiy div elementida ham onClick hodisasi ishga tushishini namoyish qilish uchun tugmani bosing:

import { createRoot } from 'react-dom/client';
import { useState } from 'react';
import { createPortal } from 'react-dom';

function PortalButton({ onClick, children }) {
  return createPortal(
    <button 
      onClick={onClick}
      style={{
        position: 'fixed',
        bottom: '20px',
        right: '20px',
        padding: '10px',
        background: 'blue',
        color: 'white'
      }}>
      {children}
    </button>,
    document.body
  );
}

function App() {
  const [count1, setCount1] = useState(0);
  const [count2, setCount2] = useState(0);

  return (
    <div
      style={{
        padding: '20px',
        border: '2px solid black',
        margin: '20px'
      }}
      onClick={() => {
        setCount1(c => c + 1);
      }}>
      <h2>Div Clicked: {count1}</h2>
      <h2>Button Clicked: {count2}</h2>      
      <p>The floating button is rendered outside this box using a portal,
          but its clicks still bubble up to this parent div!</p>
      <p>Try to click the div element as well, to see the count increase</p>
      
      <PortalButton
        onClick={(e) => {
          // This runs first
          setCount2(c => c + 1);
        }}>
        Floating Button
      </PortalButton>
    </div>
  );
}

createRoot(document.getElementById('root')).render(
  <App />
);

Misolni ishga tushirish »

Misol tushuntirildi

Ushbu misolda:

  • PortalButton componenti portal yordamida ekranning pastki o‘ng burchagiga o‘rnatilgan suzuvchi tugma sifatida ko‘rsatiladi.
  • Tugma DOMda <div> ota-onadan tashqarida mavjud bo‘lsa ham, uni bosish:
    1. Avval tugmaning o‘z onClick ishlov beruvchisini ishga tushiring (hisoblagichni oshirish)
    2. Keyin ota-ona divning onClick ishlov beruvchisini ishga tushiring
  • Bu shuni ko‘rsatadiki, hodisalarning ko‘tarilishi DOM ierarxiyasi emas, balki React componentlari ierarxiyasi orqali ishlaydi.


W3Schools Pathfinder

Yutuqlaringizni kuzating – bu bepul!