Portals در ری اکت چیست ؟ + مثال و تیکه کد از آموزش Portals در ریکت !
Portals در ری اکت یکی ویژگی خیلی جالب و کاربردی هست که به ما اجازه میده کامپوننت خودمون رو خارج از سلسله بندی کامپوننت پدر در DOM رندر کنیم. اگه این جمله براتون گنگ بود یا متوجه کاربرد پورتال در ری اکت نشدید، تو این مقاله با ما همراه باشید که میخوایم حسابی Portals در ری اکت رو به همراه تیکه کد و مثال عملی بررسی کنیم 🙂
Portals در ری اکت چیست ؟
Portals در ری اکت یک روش کاربردی برای render کردن کامپوننت، خارج از سلسه مراتب کامپوننت والد در DOM هست. یعنی ما کامپوننت خودمون رو بدون توجه به سلسه مراتبش داخل DOM قرار میدیم .
حالا شاید سوال برامون پیش بیاد که اصلا سلسله مراتب یعنی چی ؟
قبل از هرچیز لازمه اشاره کنم که برای درک پورتال در ری اکت، باید درمورد دام مجازی در ری اکت مطالعه کرده باشیم و بدونیم DOM چیه .. ( اگه درمورد دام مجازی اطلاعاتی ندارید، روی لینک آبی رنگ بالا کلیک کنید و مطالعه کنید )
موضوع این هست که کامپوننت های ما طبق یک سلسله مراتب مشخص داخل DOM مرورگر قرار میگیرن. سلسله مراتب یعنی هر کامپوننت یک پدر، پدربزرگ، فرزند و .. داره. طبیعی هست که خصوصیات پدر، به فرزند منتقل میشه.
گاهی اوغات ما نمیخوایم خصوصیات پدر به فرزند منتقل بشه.
این یعنی ما لازم داریم کامپوننت خودمون رو خارج از سلسله مراتب اون کامپوننت داخل DOM قرار بدیم. در چنین مواقعی باید از Portals در ری اکت استفاده کنیم.
کاربرد Portals در ری اکت کجاست ؟
ما اشاره کردیم که در React کامپوننت های فرزند، خصوصیات و ویژگی های کامپوننت پدرشون رو به ارث میبرن. مثلا اگه کامپوننت پدر 400px طول داشته باشه، کامپوننت فرزند نمیتونه بیشتر از 400px باشه.
حالا اگه ما لازم داشته باشیم که کامپوننت فرزند رو بصورت 800px نمایش بدیم باید چیکار کنیم ؟
راه حل استفاده از پورتال در React هست چون بدون در نظر گرفتن سلسه مراتبِ اون کامپوننت، کامپوننت رو داخل DOM رندر میکنه.
اینجوری کامپوننت ما دیگه خصوصیات کامپوننت پدرش رو به ارث نمیبره.
این مثال معمولا برای Modal ( مودال )، منو های پاپ آپ، نوتیفیکیشن ها و .. کاربرد داره چون ما میخوایم این موارد استایل های پدر خودشون رو به ارث نبرن.
چطور میشه Portals در ریکت ساخت ؟
نحوه ساخت Portals در React بصورت زیر هست :
ReactDOM.createPortal(child, container)
تابع createPortal، ساخت پورتال رو برای ما انجام میده. این تابع 2 آرگومان ورودی از ما میگیره:
آرگومان اول همون کامپوننت ماست که میخوایم خارج از سلسه مراتب render بشه ( مثل مودال )
آرگومان دوم یک اِلِمان هست که میخوایم کامپوننت ما داخل این اِلِمان رندر بشه ( ما باید این اِلِمان رو بسازیم، در ادامه میبینیم که چطور این اِلِمان رو میسازیم )
استفاده از Portals در ری اکت !
بیاید یه مثال عملی در مورد پورتال در ریکت رو باهمدیگه بررسی کنیم ..
تو مثال زیر من یک مودال ساده ساختم :
export const Modal = (props) => {
let { children, close, ...rest } = props;
if (!children) {
children = This is a example modal
;
}
return (
{children}
);
};
کامپوننت من چندین Props میگیره که کمک میکنن بتونیم کامپوننت خودمون رو کنترل کنیم مثل تابع close برای بستن مودال و children.
و فایل css کامپوننت بالارو بصورت زیر ایجاد میکنیم :
* {
font-size: 62.5%;
font-family: "Roboto";
margin: 0;
padding: 0;
}
#App {
overflow: hidden;
height: 20vh;
background-color: #ccc;
}
#App > h1 {
font-size: 2rem;
}
div#modal-dialog {
background-color: rgba(0, 0, 0, 0.8);
position: fixed;
z-index: 999;
height: 100vh;
width: 100vw;
top: 0;
left: 0;
display: flex;
align-items: center;
justify-content: center;
}
div#modal-dialog > div {
background-color: #f5f5f5;
padding: 2rem;
border-radius: 1.2rem;
}
p {
margin: 1.4rem 0;
font-size: 1.5rem;
}
button {
padding: 1rem;
border-radius: 1rem;
border: none;
background-color: #9b59b6;
color: #fff;
cursor: pointer;
transition: all 0.3s ease-in-out;
}
button:hover {
background-color: #8e44ad;
}
.flex {
display: flex;
}
.flex-col {
flex-direction: column;
}
.flex-row {
flex-direction: row;
}
.justify-center {
justify-content: center;
}
.items-center {
align-items: center;
}
تا به اینجای کار فقط یک مودال ساده درست کردیم.
ما میدونیم که تو ری اکت، اپیکیشن ما داخل یک div با آیدی root رندر میشه. حالا من به فایل index.html میرم و یک div جدید با آیدی modals درست میکنم. این دو div باید رابطه خواهر برادری داشته باشن، دقیقا مثل زیر :
React App
اگه به خط 19 دقت کنیم، میبینیم که یک div جدید با آیدی modals داریم که خارج از div اپیکیشن با آیدی root هست!
یعنی هرچیزی که داخل div دوم قرار بگیره، خارج از سلسه مراتب div اول هست و خصوصیات اون رو به ارث نمیبره!
حالا بریم فایل App.js رو بسازیم :
import { useState } from "react";
import ReactDOM from "react-dom";
import { Modal } from "./Components/Modal";
import "./styles.css";
const domElement = document.getElementById("modals");
export default function App() {
const [stateModal, setStateModal] = useState(false);
const openModal = () => setStateModal(true);
const closeModal = () => setStateModal(false);
return (
Portals Example
This is a div with a defined height and overflow hidden
{stateModal &&
ReactDOM.createPortal(
Modal from App.js
,
domElement
)}
);
}
تو خط 3 ما Modal خودمون رو فراخوانی کردیم و در خط 6 تونستیم به div خودمون که آیدی portals داشت، دسترسی پیدا کنیم. ( همون اِلِمانی که میخوایم Portals رو داخلش قرار بدیم )
همچنین در خط 9 یک state برای مشخص کردن باز یا بسته بودن modal درست کردیم.
اما مهمترین بخش تیکه کد بالا، در خط 22 وجود داره. ما یک شرط گذاشتیم ( شرط باز بودن مودال بر اساس State ) و گفتیم زمانیکه این state مقدار True داشت یک portal جدید بساز.
ساختن portal جدید به کمک ReactDOM انجام میشه. تابع createPortal از ما 2 آرگومان میگیره :
آرگومان اول همون چیزی هست که میخوایم داخل پورتال render کنیم و نمایش بدیم.
آرگومان دوم اِلِمان Portal ما هست، اگه به خط 6 دقت کنیم میبینیم که این اِلِمان رو تعریف کردیم.
در حقیقت، کل ماجرای Portals در React تو تیکه کد زیر نهفته شده :
{stateModal &&
ReactDOM.createPortal(
Modal from App.js
,
domElement
)}
ما طبق یک شرط، یک Portals در ری اکت ساختیم و نمایش دادیم.
ساخت پورتال در React به همین سادگی امکانپذیره 🙂
نتیجه تیکه کد های بالا این هست که کامپوننت Modal ما خارج از سلسله مراتب کل اپیکیشن ما ( بیرون div با آیدی root ) رندر میشه.
کاربرد اصلی پورتال در ری اکت چیست ؟
با توجه به توضیحاتی که مطرح کردیم، مهمترین کاربرد پورتال در ری اکت موارد زیر هستن :
- مودال ها
- منو های پاپ آپ ( pop-ups )
- متن های tooltips
- ناتیفیکیشن ها ( Notifications )
پورتال ها استایل های گلوبال رو نمیگیرن!
ما تو اپیکیشن خودمون کلی استایل Global داریم که روی تمام کامپوننت ها لحاظ میشن. اما با توجه به اینکه Portals خارج از سلسه مراتب DOM رندر میشه، استایل های گلوبال اپیکیشن مارو نمیگیره.
اگه استایل خاصی مدنظرمون هست، میتونیم در زمان ساخت Portals بهش پاس بدیم.
تو استفاده از Portals در ری اکت نباید زیاده روی کرد !
درسته که پورتال در ری اکت یک ویژگی خیلی کاربردی هست، اما باید فقط در موارد ضروری ازش استفاده کنیم. استفاده بیش از حد از پورتال در ریکت باعث تکه تکه شدن DOM اپیکیشن ما میشه و نگهداری اپیکیشن و خوانایی کد رو سخت میکنه.
پس درسته که پورتال یک قابلیت ارزشمند در کتابخانه ری اکت به حساب میاد اما فقط باید در موارد ضروری ازش استفاده کرد 🙂
Portals در ری اکت یک روش برای Render کردن کامپوننت در DOM، خارج از سلسه مراتب کامپوننت پدر هست. این یعنی کامپوننت ما خصوصیات و استایل های کامپوننت پدرش رو به ارث نمیبره.
فرض کنیم ما یک کامپوننت مودال داریم.
کامپوننت پدر این مودال، طول و عرض 200 پیکسلی داره.
این یعنی ما نمیتونیم مودال خودمون رو 600 پیکسل نمایش بدیم چون کامپوننت مودال، استایل پدر خودش رو به ارث میبره.
راه حل Portals هست که کمک میکنه کامپوننت خودمون رو خارج از سلسله مراتب کامپوننت پدر در DOM رندر کنیم.
درباره احمد احمدنژاد
من یه برنامه نویس و توسعه دهنده وب هستم که عاشق دنیای صفر و یکم❤️
نوشتههای بیشتر از احمد احمدنژاد2 دیدگاه
به گفتگوی ما بپیوندید و دیدگاه خود را با ما در میان بگذارید.
سلام و عرض ادب
استاد میشه در رابطه با useFetcher آموزش بذارید
سلام رضا جان امیدوارم حالت خوب باشه
حتما 🙂 چرا که نه
بزودی مقاله آموزشیش رو مینویسم و منتشر میکنم.
ممنون از پیشنهادی که دادی