برنامه نویسی 24 بازدید

کادرهای Modal می‌توانند موضوعات پیچیده‌ای باشند، زیرا روش ری‌اکت برای سازماندهی DOM چنین است. اگر با مبانی ری‌اکت آشنا باشید، می‌دانید که کل اپلیکیشن یک کامپوننت است که معمولاً </ App> نامیده می‌شود و به عنوان یک فرزند به یک <div> به نام root# الحاق می‌شود. فایل index.html چیزی مانند زیر است:

ری‌اکت
فایل public/index.html برای ایجاد ری‌اکت

زمانی که کامپوننت </ App> در DOM رندر شد، عنصر واقعی <div> در HTML با id #root کل اپلیکیشن React را درون خود رندر می‌کند.

در نتیجه، این وضعیت که کامپوننت‌های اپلیکیشن React کاملاً تو در تو باشند، امری رایج محسوب می‌شود. منظور ما از تو در تو، ده‌ها سطح و یا بیشتر است. بنابراین اگر یکی از این سطوح کاملاً عمیق در لایه‌های تو در تو بخواهد یک modal را نمایش دهد، با برخی مشکلات جدی CSS مواجه می‌شود.

Modal-ها یک لایه روی صفحه قرار می‌دهند و از این رو اولویت نمایشی بالاتری نسبت به همه عناصر دیگر دارند. اگر بخواهید آن را برحسب z-index تعیین کنید، باز هم کاملاً تو در تو خواهد بود و عناصر والد در سطوح بالاتر CSS تقدم خواهند داشت.

بنابراین به جای این که با CSS سر و کله بزنیم که به تنظیم دقیق نیاز دارد و هر آن ممکن است اپلیکیشن را به هم بریزد، باید روشی برای رندر کردن DOM در خارج از این ساختار کاملاً تو در تو پیدا کنیم.

راه‌حل: پورتال‌های React

یک راهبرد استفاده از پورتال‌های ReactDOM است و بدین ترتیب Modal را در یک div قرار می‌دهیم که کامپوننت هم‌نیای div با id به صورت #root است. بدین ترتیب سبک‌های CSS اعمال شده روی div wrapper برای Modal تنها در رابطه با هم‌نیای آن که root# است، اعمال می‌شوند و از این رو سبک‌بندی CSS برای root# به هم نمی‌ریزد.

برای انجام این کار باید از متد ()createPortal در ReactDOM استفاده کنیم. یک پورتال عملاً یک div هم‌نیا است و این قاعده را که همه کامپوننت‌های React باید فرزندان <“div id=”root> باشند را دور می‌زند. به این منظور باید کارهای زیر را انجام دهیم:

کد زیر را در فایل index.html و درون تگ <body> قرار دهید:

یک کامپوننت Modal.js ایجاد کنید (classNames از semantic-UI گرفته شده):

می‌بینید که createPortal دو آرگومان می‌گیرد که در یکی برخی اسکریپت‌های JSX که رندر می‌شوند و مشابه ReactDOM.render هستند و دیگری عنصر هدف است که باید JSX را رندر کند.

اگر کامپوننت را رندر و به آن مراجعه کنید، مشاهده خواهید کرد که همه چیز به درستی نمایش می‌یابد. اینک باید handler مناسب را به ()onClick اضافه کنید تا زمانی که کاربر درون رابط کاربری modal کلیک کرد عمل مناسب را انجام دهد و در صورتی که خارج از آن کلیک کرد نیز آن را پنهان سازد.

این کار از طریق شنود کلیک‌ها در ناحیه مناسب و سپس متوقف کردن انتشار modal صورت می‌گیرد و به این ترتیب رفتارهای صحیحی بسته به این که کاربر کجا کلیک کرده است بروز می‌یابد.

قابلیت استفاده مجدد (Reusability)

مثال فوق کاملاً ابتدایی است و قصد ما نیز این نبوده که یک قطعه کد آماده استفاده ارائه کنیم. بلکه، کدی که ما نوشته‌ایم یک راه‌حل است که برای رفع مشکل modal-ها ارائه شده است. شما باید این کامپوننت را بر اساس نیازهای خودتان سفارشی‌سازی کنید. از مفاهیم React برای قابلیت استفاده مجدد استفاده کنید تا مطمئن شوید که داده‌های کدنویسی شده سخت (یعنی داده‌هایی که قابلیت استفاده مجدد نمی‌یابند) در Modal ندارید و محتوا و حتی ویجت‌های کوچک را نیز بنا به نیاز ارسال می‌کنید.

برای نمونه می‌توانید یک modal داشته باشید که وقتی کاربر قصد دارد چیزی را از پایگاه داده حذف کند، نمایش دهید. این کامپوننت می‌تواند نامی مانند </DeleteThis> داشته باشد. این کامپوننت یک </ Modal> است یعنی که یک لایه رویی است که صفحه </ DeleteThis> زیرین را تیره می‌کند.

درون </ Modal> یک کامپوننت داخلی به نام </ InnerModal> قرار دارد و این کامپوننت همان کامپوننت تعاملی اصلی را در خود جای داده است که هدر، محتوا و متن دارد.

بنابراین کامپوننت </ DeleteThis> اقدام به ایجاد props می‌کند که به <Modal /> ارسال می‌شود و به نوبه خود در </ InnerModal> قرار می‌گیرد. از این رو متد رندر </ DeleteThis> به صورت زیر خواهد بود:

کامپوننت واقعی  Modal به صورت زیر است:

و اینک در نهایت می‌توانیم آن را رندر کنیم:

Modal

بدین ترتیب موفق شدیم این کار را به انجام برسانیم و اینک Modal-ها با پورتال React کار می‌کنند.

اگر این مطلب برای شما مفید بوده است، آموزش‌های زیر نیز به شما پیشنهاد می‌شوند:

==

به عنوان حامی، استارتاپ، محصول و خدمات خود را در انتهای مطالب مرتبط مجله فرادرس معرفی کنید.

telegram
twitter

میثم لطفی

«میثم لطفی» دانش‌آموخته کارشناسی ریاضیات کاربردی و شیفته فناوری به خصوص در حوزه رایانه است. وی در حال حاضر علاوه بر پیگیری همه علاقه‌مندی‌های خود در رشته‌های برنامه‌نویسی، کپی‌رایتینگ و تولید محتوای چندرسانه‌ای، در زمینه نگارش مقالاتی با محوریت نرم‌افزار نیز با مجله فرادرس همکاری دارد.

آیا این مطلب برای شما مفید بود؟

نظر شما چیست؟

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *