createPortal

createPortal আপনাকে DOM-এর ভিন্ন অংশে কিছু চাইল্ড রেন্ডার করতে দেয়।

<div>
<SomeComponent />
{createPortal(children, domNode, key?)}
</div>

রেফারেন্স

createPortal(children, domNode, key?)

একটি পোর্টাল তৈরি করতে, createPortal কল করুন, কিছু JSX এবং DOM নোড পাস করুন যেখানে এটি রেন্ডার করা হবেঃ

import { createPortal } from 'react-dom';

// ...

<div>
<p>This child is placed in the parent div.</p>
{createPortal(
<p>This child is placed in the document body.</p>,
document.body
)}
</div>

নীচে আরও উদাহরণ দেখুন।

একটি পোর্টাল কেবল DOM নোডের physical অবস্থান পরিবর্তন করে। অন্যান্য সকল উপায়ে, আপনি যে JSX পোর্টালে রেন্ডার করেন তা React কম্পোনেন্টের একটি চাইল্ড নোড হিসাবে কাজ করে যা এটিকে রেন্ডার করে। উদাহরণস্বরূপ, চাইল্ড প্যারেন্ট ট্রি দ্বারা প্রদত্ত কনটেক্স্ট অ্যাক্সেস করতে পারে, এবং ইভেন্টগুলি চাইল্ড থেকে প্যারেন্টদের কাছে React ট্রি অনুসারে বুদবুদ করে উঠে।

প্যারামিটার

  • children: যেকোনো জিনিস যা React দ্বারা রেন্ডার করা যায়, যেমন একটি JSX অংশ (উদাহরণস্বরূপ <div /> বা <SomeComponent />), একটি ফ্র্যাগমেন্ট (<>...</>), একটি স্ট্রিং বা একটি সংখ্যা, অথবা এগুলির একটি অ্যারে।

  • domNode: কিছু DOM নোড, যেমন document.getElementById() দ্বারা ফেরত আসা নোডগুলি। নোডটি ইতোমধ্যে বিদ্যমান থাকতে হবে। আপডেটের সময় ভিন্ন DOM নোড পাস করা হলে পোর্টাল কন্টেন্ট পুনরায় তৈরি করা হবে।

  • ঐচ্ছিক key: পোর্টালের কী হিসাবে ব্যবহার করার জন্য একটি অনন্য স্ট্রিং বা সংখ্যা।

রিটার্নস

createPortal একটি React নোড ফেরত দেয় যা JSX-এ অন্তর্ভুক্ত করা যেতে পারে বা একটি React কম্পোনেন্ট থেকে ফেরত দেওয়া যেতে পারে। যদি React এটি রেন্ডার আউটপুটে দেখে, এটি প্রদত্ত children-কে প্রদত্ত domNode-এর মধ্যে রাখবে।

সাবধানতা

  • পোর্টাল থেকে ইভেন্টগুলি DOM ট্রি নয়, বরং React ট্রি অনুসারে এগিয়ে যায়। উদাহরণস্বরূপ, যদি আপনি একটি পোর্টালের ভেতরে ক্লিক করেন, এবং পোর্টালটি <div onClick>-এ wrap করা থাকে, তাহলে onClick হ্যান্ডলারটি ফায়ার হবে। যদি এটি সমস্যা তৈরি করে, তাহলে পোর্টালের ভেতরে event propagation বন্ধ করুন, অথবা পোর্টালটি React ট্রিতে উপরের দিকে উঠিয়ে নিন।

ব্যবহার

DOM-এর ভিন্ন একটি অংশে রেন্ডারিং

পোর্টাল আপনার কম্পোনেন্টগুলিকে তাদের কিছু চাইল্ডকদ DOM-এর ভিন্ন স্থানে রেন্ডার করতে দেয়। এটি আপনার কম্পোনেন্টের একটি অংশকে যেকোনো কন্টেইনার থেকে “মুক্ত” করে। উদাহরণস্বরূপ, একটি কম্পোনেন্ট একটি মডাল ডায়লগ বা একটি টুলটিপ প্রদর্শন করতে পারে যা বাকি পৃষ্ঠার উপরে এবং বাইরে প্রদর্শিত হয়।

একটি পোর্টাল তৈরি করতে, createPortal-এর ফলাফল রেন্ডার করুন কিছু JSX এবং DOM নোডে যেখানে এটি যাওয়া উচিত:

import { createPortal } from 'react-dom';

function MyComponent() {
return (
<div style={{ border: '2px solid black' }}>
<p>This child is placed in the parent div.</p>
{createPortal(
<p>This child is placed in the document body.</p>,
document.body
)}
</div>
);
}

React আপনি যে JSX পাস করেছেন এর DOM নোডগুলি আপনার প্রদত্ত DOM নোডের মধ্যে রাখবে।

একটি পোর্টাল ছাড়া, দ্বিতীয় <p> প্যারেন্ট <div>-এর ভেতরে স্থাপন করা হত, কিন্তু পোর্টালটি এটিকে document.body: এ “টেলিপোর্ট” করেছে।

import { createPortal } from 'react-dom';

export default function MyComponent() {
  return (
    <div style={{ border: '2px solid black' }}>
      <p>This child is placed in the parent div.</p>
      {createPortal(
        <p>This child is placed in the document body.</p>,
        document.body
      )}
    </div>
  );
}

লক্ষ্য করুন কিভাবে দ্বিতীয় প্যারাগ্রাফ দৃশ্যত বর্ডার সহ প্যারেন্ট <div>-এর বাইরে প্রদর্শিত হচ্ছে। যদি আপনি ডেভেলপার টুলস দ্বারা DOM কাঠামো পরীক্ষা করেন, আপনি দেখবেন যে দ্বিতীয় <p> সরাসরি <body>-তে রাখা হয়েছে:

<body>
<div id="root">
...
<div style="border: 2px solid black">
<p>This child is placed inside the parent div.</p>
</div>
...
</div>
<p>This child is placed in the document body.</p>
</body>

একটি পোর্টাল কেবল DOM নোডের physcial অবস্থান পরিবর্তন করে। অন্যান্য সকল উপায়ে, আপনি যে JSX পোর্টালে রেন্ডার করেন তা React কম্পোনেন্টের একটি চাইল্ড নোড হিসেবে কাজ করে যা এটিকে রেন্ডার করে। উদাহরণস্বরূপ, চাইল্ড প্যারেন্ট ট্রি দ্বারা প্রদত্ত কনটেক্স্ট অ্যাক্সেস করতে পারে, এবং ইভেন্টগুলি চাইল্ড থেকে প্যারেন্টের কাছে React ট্রি অনুসারে বুদবুদ করে উপরে উঠে।


একটি পোর্টাল দ্বারা মোডাল ডায়লগ রেন্ডার করা

আপনি একটি পোর্টাল ব্যবহার করে একটি মোডাল ডায়লগ তৈরি করতে পারেন যা পেইজের বাকি অংশের উপরে ভাসমান, এমনকি যদি ডায়লগ কল করা কম্পোনেন্টটি overflow: hidden বা অন্যান্য স্টাইল যা ডায়লগের সাথে বাধা দেয় এমন কন্টেইনারের মধ্যে থাকে।

এই উদাহরণে, দুটি কন্টেইনারের স্টাইলগুলি মডাল ডায়লগের জন্য বিঘ্ন ঘটাচ্ছে, কিন্তু পোর্টালে রেন্ডার করা একটি অপ্রভাবিত থাকে, কারণ DOM-এ, মোডালটি প্যারেন্ট JSX উপাদানগুলির মধ্যে contained নয়।

import NoPortalExample from './NoPortalExample';
import PortalExample from './PortalExample';

export default function App() {
  return (
    <>
      <div className="clipping-container">
        <NoPortalExample  />
      </div>
      <div className="clipping-container">
        <PortalExample />
      </div>
    </>
  );
}

সতর্কতা

পোর্টাল ব্যবহার করার সময় আপনার অ্যাপটি অ্যাক্সেসিবল হওয়া নিশ্চিত করা গুরুত্বপূর্ণ। উদাহরণস্বরূপ, আপনাকে কীবোর্ড ফোকাস পরিচালনা করতে হতে পারে যাতে ব্যবহারকারী স্বাভাবিকভাবে পোর্টালের ভিতরে এবং বাইরে ফোকাস নড়াতে পারে।

মডাল তৈরি করার সময় WAI-ARIA Modal Authoring Practices অনুসরণ করুন। যদি আপনি কোনো কমিউনিটি প্যাকেজ ব্যবহার করেন, নিশ্চিত করুন যে এটি অ্যাক্সেসিবল এবং এই নির্দেশিকাগুলি অনুসরণ করে।


নন-React সার্ভার মার্কআপে React কম্পোনেন্টগুলি রেন্ডার করা

যদি আপনার React রুট স্ট্যাটিক বা সার্ভার-রেন্ডার করা পেইজের শুধুমাত্র একটি অংশ হয় যা React দ্বারা তৈরি নয়, তাহলে পোর্টাল উপকারী হতে পারে। উদাহরণস্বরূপ, যদি আপনার পেইজ Rails বা অন্য কোনো সার্ভার ফ্রেমওয়ার্ক দ্বারা তৈরি হয়, আপনি সাইডবারের মতো স্ট্যাটিক অঞ্চলের মধ্যে ইন্টার‌্যাক্টিভ এলাকা তৈরি করতে পারেন। আলাদা আলাদা React রুটের তুলনায়, পোর্টালগুলি আপনাকে অ্যাপটিকে একটি একক React ট্রি হিসাবে আচরণ করতে দেয় যার shared স্টেট রয়েছে, যদিও এর অংশগুলি DOM-এর ভিন্ন ভিন্ন অংশে রেন্ডার হয়।

import { createPortal } from 'react-dom';

const sidebarContentEl = document.getElementById('sidebar-content');

export default function App() {
  return (
    <>
      <MainContent />
      {createPortal(
        <SidebarContent />,
        sidebarContentEl
      )}
    </>
  );
}

function MainContent() {
  return <p>This part is rendered by React</p>;
}

function SidebarContent() {
  return <p>This part is also rendered by React!</p>;
}


নন-React DOM নোডে React কম্পোনেন্টগুলি রেন্ডার করা

আপনি একটি পোর্টাল ব্যবহার করেও React এর বাইরে পরিচালিত DOM নোডের কন্টেন্ট পরিচালনা করতে পারেন। উদাহরণস্বরূপ, ধরুন আপনি একটি নন-React ম্যাপ উইজেটের সাথে সংযোজন করছেন এবং আপনি একটি পপআপের মধ্যে React কন্টেন্ট রেন্ডার করতে চান। এটি করতে, popupContainer নামক একটি স্টেট ভেরিয়েবল ঘোষণা করুন যেখানে আপনি রেন্ডার করতে যাচ্এঁরন সেই DOM নোডটি সংরক্ষণ করবেন

const [popupContainer, setPopupContainer] = useState(null);

যখন আপনি থার্ড-পার্টি উইজেট তৈরি করবেন, উইজেট দ্বারা ফেরত আসা DOM নোডটি সংরক্ষণ করুন যাতে আপনি এতে রেন্ডার করতে পারেন:

useEffect(() => {
if (mapRef.current === null) {
const map = createMapWidget(containerRef.current);
mapRef.current = map;
const popupDiv = addPopupToMapWidget(map);
setPopupContainer(popupDiv);
}
}, []);

এটি আপনাকে createPortal ব্যবহার করে popupContainer-এ React কন্টেন্ট রেন্ডার করতে দেয় যখন এটি available হয়:

return (
<div style={{ width: 250, height: 250 }} ref={containerRef}>
{popupContainer !== null && createPortal(
<p>Hello from React!</p>,
popupContainer
)}
</div>
);

এখানে একটি সম্পূর্ণ উদাহরণ রয়েছে যা নিয়ে আপনি ঘাটাঘাটি করতে পারেন:

import { useRef, useEffect, useState } from 'react';
import { createPortal } from 'react-dom';
import { createMapWidget, addPopupToMapWidget } from './map-widget.js';

export default function Map() {
  const containerRef = useRef(null);
  const mapRef = useRef(null);
  const [popupContainer, setPopupContainer] = useState(null);

  useEffect(() => {
    if (mapRef.current === null) {
      const map = createMapWidget(containerRef.current);
      mapRef.current = map;
      const popupDiv = addPopupToMapWidget(map);
      setPopupContainer(popupDiv);
    }
  }, []);

  return (
    <div style={{ width: 250, height: 250 }} ref={containerRef}>
      {popupContainer !== null && createPortal(
        <p>Hello from React!</p>,
        popupContainer
      )}
    </div>
  );
}