پورتالها (Portals)، یکی از قابلیتهای جدیدی هستند که در React 16 به دنیای React اضافه شدند. این قابلیت به شما این امکان را میدهد که یک کامپوننت را به خارج از محدوده (scope) DOM tree تزریق کنید و بتوانید آن را در مکان دیگری در ساختار DOM اضافه کنید. در این بخش این مفهوم را بررسی می کنیم. برای اطلاعات بیشتر می توانید به دوره آموزش ری اکت مراجعه کنید.
اما چرا از پورتالها استفاده میشود؟ در بسیاری از موارد، به دلیل محدودیتهای CSS و layout ها، نیاز به اضافه کردن کامپوننت به DOM در مکانی خارج از ساختار DOM برای نمایش آن به صورت مناسب وجود دارد. برای مثال، فرض کنید یک کامپوننت داریم که یک منوی کشویی را نشان میدهد، اما میخواهیم این منو را در بالای صفحه نمایش دهیم، در حالی که کامپوننت مربوط به منو در یک قسمت دیگر از ساختار DOM قرار دارد. به جای استفاده از روشهای سنتی که امکان تغییر ساختار DOM را دارند، با استفاده از پورتالها میتوانیم کامپوننت را به راحتی به مکان مورد نظر در ساختار DOM منتقل کنیم.
برای استفاده از پورتالها، شما باید یک پورتال جدید ایجاد کنید. برای این کار، شما میتوانید از کامپوننت React Portal استفاده کنید. این کامپوننت به عنوان یک پورتال برای انتقال کامپوننتها به مکان مورد نظر در ساختار DOM عمل میکند.
برای استفاده از کامپوننت React Portal، می توانیم چنین پیاده سازی داشته باشیم:
import React from 'react';
import ReactDOM from 'react-dom';
const App = () => {
return ReactDOM.createPortal(
<h1>Hello world!</h1>,
document.getElementById('my-portal')
);
}
export default App;
در این مثال، یک کامپوننت به نام App داریم که از کامپوننت React Portal برای ایجاد یک پورتال استفاده میکند. این کامپوننت به صورت پیشفرض به عنوان فرزندان خود، همهی کامپوننتهای داخلی را به مکانی خاص در ساختار DOM انتقال میدهد.
در دومین پارامتر از تابع ReactDOM.createPortal، شناسه (ID) مکانی که میخواهیم کامپوننت خود را به آن انتقال دهیم، را ارائه میدهیم. در این مثال، این شناسه با my-portal تعریف شده است. شناسه مورد استفاده باید به یک المان موجود در ساختار DOM اشاره کند. که این تعریف در فایل index.html انجام می شود
همانطور که مشاهده میکنید، استفاده از کامپوننت React Portal بسیار ساده است و باعث میشود که بتوانید به راحتی یک پورتال جدید ایجاد کنید. با استفاده از پورتالها، میتوانید کامپوننتهای خود را به سادگی در ساختار DOM به مکانهای دیگر منتقل کنید و بهترین نمایش را در سایت خود برای کاربران خود فراهم کنید
چند مورد از کاربردهای پورتال
پورتالها در ریاکت به عنوان یک راهکار مناسب برای کاربردهای مختلفی استفاده میشوند. در زیر چند مورد از کاربردهای پرتالها را بررسی خواهیم کرد:
-
نمایش منو و یا کامپوننتهای دیگر در بالای صفحه: یکی از مهمترین کاربردهای پورتالها در ریاکت، نمایش منو و یا کامپوننتهای دیگر در بالای صفحه است. در اینجا پورتال به کار میرود تا اجزای مربوط به منو و یا کامپوننت دیگر، به صورت مجزا از بقیه ساختار DOM در یک محیط جداگانه قرار گیرند و در نهایت بالای صفحه نمایش داده شوند.
-
نمایش مدالها (Modal): استفاده از پورتال برای نمایش مدالها (Modal) نیز بسیار مفید است. با استفاده از پورتال، میتوانید مدالهای خود را به صورت مجزا از بقیه ساختار DOM در یک محیط جداگانه نمایش دهید تا کاربران متوجه شوند که در حال حاضر در یک حالت خاص قرار دارند.
-
نمایش تبلیغات یا پیامهایی در بالای صفحه: استفاده از پورتال برای نمایش تبلیغات یا پیامهایی در بالای صفحه نیز میتواند بسیار مفید باشد. با استفاده از پورتال، میتوانید پیامهای خود را به صورت مجزا در یک محیط جداگانه قرار داده و در بالای صفحه نمایش دهید تا کاربران به راحتی بتوانند آنها را مشاهده کنند.
-
نمایش فرمهای پر کاربرد: در بسیاری از صفحات وب، فرمهایی که بسیار پرکاربرد هستند (مانند فرمهای ورود و ثبت نام) وجود دارند.
در اینجا نیز پورتال به کار میرود تا فرمهای مذکور به صورت مجزا در یک محیط جداگانه قرار گیرند و به کاربران اجازه دهند که به راحتی با آنها ارتباط برقرار کنند.
-
نمایش فهرستهای بزرگ: همچنین پورتالها میتوانند به خوبی برای نمایش فهرستهای بزرگ که نیاز به اسکرول دارند، استفاده شوند. در این حالت، فهرست مذکور به صورت مجزا در یک محیط جداگانه قرار میگیرد و کاربران میتوانند به راحتی با آن تعامل داشته باشند.
-
نمایش اعلانها: استفاده از پورتال برای نمایش اعلانها نیز بسیار مفید است. با استفاده از پورتال، میتوانید اعلانهای خود را به صورت مجزا در یک محیط جداگانه نمایش دهید تا کاربران به راحتی بتوانند آنها را مشاهده کنند.
-
نمایش پنجرههای داخلی: همچنین، پورتالها میتوانند به خوبی برای نمایش پنجرههای داخلی به کار روند. در این حالت، پنجره مذکور به صورت مجزا در یک محیط جداگانه قرار میگیرد و کاربران میتوانند به راحتی با آن تعامل داشته باشند.
به طور کلی، پورتالها به عنوان یک راهکار قابل اعتماد و منعطف در ریاکت مورد استفاده قرار میگیرند و برای کاربردهای مختلفی مانند نمایش منو، فرمهای پرکاربرد، تبلیغات، اعلانها و پنجرههای داخلی به کار میروند.
در چه شرایطی نباید از پورتال استفاده کرد؟
استفاده از پورتال در برخی شرایط ممکن است مناسب نباشد. برای مثال:
-
در صورتی که قرار است که محتوای نمایش داده شده توسط پورتال بسیار ساده باشد، احتمالاً بهتر است از روشهای سادهتری برای نمایش آن استفاده کنید.
-
در برخی موارد، استفاده از پورتال ممکن است باعث کاهش سرعت سایت شود، به خصوص اگر از پورتالهای بسیار بزرگ و پیچیده استفاده کنید.
-
در صورتی که نیاز به دسترسی به دادههای پدری ندارید، ممکن است بهتر باشد از روشهای سادهتری برای نمایش محتوا استفاده کنید.
به طور کلی، استفاده از پورتال بسته به شرایط میتواند مناسب یا نامناسب باشد. بنابراین، برای استفاده بهینه از آن، باید شرایط استفاده را دقیقاً ارزیابی کرده و از آن در صورت لزوم به دلیلهای فنی و طراحی استفاده کرد.
پیاده سازی یک Dropdown Menu
فرض کنید که یک کامپوننت DropdownMenu درست کردهاید. این کامپوننت باید دو دکمه داشته باشد: یک دکمه برای باز کردن و بستن منو و دکمه دیگری برای نمایش فرم. برای نمایش منو، میتوانید از پورتال استفاده کنید: -
import React, { useState } from 'react';
import ReactDOM from 'react-dom';
function DropdownMenu({ form }) {
const [isOpen, setIsOpen] = useState(false);
const toggleOpen = () => setIsOpen(!isOpen);
return (
<>
<button onClick={toggleOpen}>
{isOpen ? 'Close Menu' : 'Open Menu'}
</button>
{isOpen && (
ReactDOM.createPortal(
<div className="menu">
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</div>,
document.querySelector('#menu-root')
)
)}
<button onClick={() => form.toggle()}>
Show Form
</button>
</>
);
}
export default DropdownMenu;
در این کد، از useState برای ردیابی وضعیت منو استفاده میشود. هنگامی که کاربر بر روی دگمه منو کلیک میکند، toggleOpen فراخوانی میشود و isOpen به صورت متناظر با وضعیت جدید تغییر میکند. همچنین، در این کد، با استفاده از createPortal، منو به بالای صفحه نمایش منتقل میشود و در id menu-root قرار میگیرد.
همچنین، در این مثال، یک فرم به عنوان ورودی به کامپوننت پاس داده شده است. هنگامی که کاربر بر روی دگمه نمایش فرم کلیک میکند، تابع form.toggle فراخوانی میشود و فرم نمایش داده مشود. این مثال از این نکته بسیار خوبی برای استفاده از پورتال بهره برده است: بیش از یک ریشه DOM داریم. منو در داخل ریشه اصلی، ولی در بالای صفحه نمایش نمایش داده میشود. این کد از createPortal به عنوان یک راه حل استفاده میکند.
همچنین در کامپوننت App، میتوانید #menu-root را در داخل بدنه قرار دهید:
function App() {
const [formOpen, setFormOpen] = useState(false);
const toggleForm = () => setFormOpen(!formOpen);
return (
<div>
<DropdownMenu form={{ open: formOpen, toggle: toggleForm }} />
{formOpen && (
<form>
<label>
Name:
<input type="text" name="name" />
</label>
<input type="submit" value="Submit" />
</form>
)}
<div id="menu-root"></div>
</div>
);
}
export default App;
در این کد، دو کامپوننت DropdownMenu به فرم اضافه شدهاند. همچنین، به شیوهای که پیشتر ذکر شد، #menu-root به عنوان ریشه دوم پورتال در نظر گرفته شده است.
با استفاده از این کد، در کامپوننت App، یک نمونه از DropdownMenu را رندر میکنیم. هنگامی که کاربر بر روی دگمه نمایش فرم کلیک میکند، فرم نمایش داده میشود.
میتوانید کد را اجرا کنید و خروجی را ببینید.
در آخر این مقاله لازم به ذکر است برای بررسی دقیق تر این مفهوم با پیاده سازی سیستم های واقعی می توانید در دوره آموزش React شرکت کنید