দুটো ছোট, নির্দিষ্ট টুল যা দুটো অসম্পর্কিত সমস্যা সমাধান করে: পাতায় জঞ্জাল যোগ না করে JSX-এর এক-root-এলিমেন্ট নিয়ম মেনে চলা, আর কম্পোনেন্ট ট্রিতে যেখানে লেখা আছে তার বাইরে কিছু রেন্ডার করা।
JSX Syntax পাঠে দেখানো হয়েছিল একটি কম্পোনেন্ট শুধু একটি root এলিমেন্ট রিটার্ন করতে পারে — সাধারণ সমাধান হলো সবকিছু একটি <div>-এ মোড়ানো। কিন্তু সেই অতিরিক্ত <div> আসল পাতায় একটি প্রকৃত এলিমেন্ট হয়ে যায়, যা নির্দিষ্ট parent-child সম্পর্ক প্রত্যাশা করা CSS ভেঙে দিতে পারে (উদাহরণস্বরূপ একটি CSS grid, যেখানে প্রতিটি সরাসরি child গুরুত্বপূর্ণ):
function TableRow() {
return (
<tr>
{/* An extra <div> here would be invalid HTML inside a <tr> */}
</tr>
);
}একটি Fragment একটি <div> যেভাবে করত সেভাবেই এলিমেন্ট গ্রুপ করে, কিন্তু আসল DOM-এ কোনো চিহ্ন রেখে যায় না:
import { Fragment } from 'react';
function ItemDetails() {
return (
<Fragment>
<dt>Name</dt>
<dd>Priya</dd>
</Fragment>
);
}
// The shorthand — used almost everywhere in real code:
function ItemDetails() {
return (
<>
<dt>Name</dt>
<dd>Priya</dd>
</>
);
}শর্টহ্যান্ডের একটি সীমাবদ্ধতা আছে
<>...</> শর্টহ্যান্ড একটি key প্রপ নিতে পারে না — (Rendering Lists and Keys পাঠ থেকে) একটির দরকার এমন একটি .map()-এর ভেতরে, এর বদলে সম্পূর্ণ <Fragment key={...}> রূপ ব্যবহার করুন।
একটি portal একটি কম্পোনেন্টের আউটপুট সম্পূর্ণ ভিন্ন একটি DOM node-এ রেন্ডার করে, যদিও এটা বাকি সবকিছুর জন্য (props, context, ইভেন্ট bubbling) React কম্পোনেন্ট ট্রিতে তার স্বাভাবিক জায়গায় থাকে। এটা একটি আসল CSS সমস্যা সমাধান করে: overflow: hidden বা একটি সীমাবদ্ধ z-index-সহ একটি কম্পোনেন্টের গভীরে নেস্ট করা একটি মোডাল বা টুলটিপ এর বদলে সরাসরি document.body-তে রেন্ডার করে সেই কন্টেইনার থেকে দৃশ্যত পালাতে পারে:
import { createPortal } from 'react-dom';
function Modal({ children }) {
return createPortal(
<div className="modal-overlay">{children}</div>,
document.body
);
}Modal তবুও ঠিক অন্য যেকোনো কম্পোনেন্টের মতো লেখা আর ব্যবহার করা যায় — <Modal>...</Modal> — এটা কীভাবে কল করা হয় তা নিয়ে কিছু বদলায় না; শুধু এর মার্কআপ শারীরিকভাবে DOM-এ কোথায় শেষ হয় তা বদলায়।