<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های Hasan</title>
        <link>https://virgool.io/feed/@Hasan-Mir</link>
        <description></description>
        <language>fa</language>
        <pubDate>2026-06-19 11:23:37</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/1343838/avatar/sw8sc2.jpeg?height=120&amp;width=120</url>
            <title>Hasan</title>
            <link>https://virgool.io/@Hasan-Mir</link>
        </image>

                    <item>
                <title>تغییرات و ویژگی‌های جدید 6 React Router - قسمت دوم</title>
                <link>https://virgool.io/@Hasan-Mir/%D8%AA%D8%BA%DB%8C%DB%8C%D8%B1%D8%A7%D8%AA-%D9%88-%D9%88%DB%8C%DA%98%DA%AF%DB%8C-%D9%87%D8%A7%DB%8C-%D8%AC%D8%AF%DB%8C%D8%AF-6-react-router-%D9%82%D8%B3%D9%85%D8%AA-%D8%AF%D9%88%D9%85-dlm6wt46rj7t</link>
                <description>React Router v6به نام خداسلامخب، در ادامه قسمت اول ببینیم دیگه چه چیزای جدیدی در نسخه 6 ریکت‌روتر داریم؟بخش هفتم: Descendant Routesدر قسمت اول و بخش ششم گفتیم که برای داشتن Nested Route ها نیازی نیست مثل نسخه 5 بیایم روت ها رو داخل خود کامپوننت قرار بدیم، بلکه خود &lt;Route&gt; ها رو تودرتو استفاده میکردیم و با استفاده از کامپوننت Outlet که در نسخه 6 معرفی شده مشخص میکنیم در فلان روت، کامپوننت متناظر اون روت، کجا رندر بشه؟اما در این نسخه هم میتونیم مثل نسخه قبل، &lt;Route&gt; ها رو داخل خود کامپوننت پدرشون(اونجایی که قراره رندر بشن) قرار بدیم و از Outlet استفاده نکنیم. منتها چندتا نکته وجود داره:1- Route ها حتما باید داخل &lt;Routes&gt; قرار بگیرن.(در قسمت اول، بخش اول بهش اشاره کردیم)2- آدرس Route ها نسبیه (لزومی نداره در ابتدای اونها از / استفاده کنیم)3- باید یک  */  به انتهای مسیر(path) Parent Route اضافه کنیم. اگر این کار رو نکنیم، parent route وقتی که URL طولانی­تر از مسیر parent route هست و یه اضافاتی دنبالش داره، باهاش جور نمیشه و کامپوننت رندر نمیشه و در نتیجه اون Route ها درونش رندر نمیشن.Descendant Routesمثلا آدرس سایت ما site.com هست، در کد بالا گفتیم کلا هر آدرسی بود، هر چی بعد از /site.com بود، شما بیا کامپوننت Layout رو رندر کن و داخل کامپوننت Layout هم دو تا Route تعریف کردیم(حتما باید داخل Routes باشن) که اگر آدرس site.com/invoices بود، Invoices رندر میشه و اگر site.com/dashboard بود، Dashboard رندر میشه.اینجا اگر اون */ رو ننویسیم و آدرسم مثلا site.com/abcd باشه، چون آدرس با path ای که به Route دادیم جور نیست، کامپوننت Layout رندر نمیشه و در نتیجه روت های داخل اونهم رندر نمیشن.بخش هشتم: Multiple sets of Routesدر یک کامپوننت میتونیم، چندین &lt;Routes&gt; داشته باشیم که هر کدوم به صورت مستقل اجرا میشن و برحسب URL ،یکی از &lt;Route&gt; های داخلشون رو انتخاب میکنن و رندر میکنن.این زمانی کاربردیه که بخوایم براساس یک URL ، چندتا کامپوننت مختلف رو در بخش های مختلف رندر کنیم:Multiple sets of Routesاینجا وقتی در  /  باشیم، هم کامپوننت Home رندر میشه هم MainNav ، چون &lt;Routes&gt; ها به صورت مستقل کار میکنن.بخش نهم: Index Routeاین مفهوم در واقع default child Route حساب میشه. وقتی یه parent route چندتا فرزند داره و URL در مسیر parent route هست، اگر بخوایم یکی از اون child route ها رو به صورت پیشفرض رندر کنیم: =&gt; یک Route جدید تعریف میکنیم و به جای path از ویژگی index استفاده میکنیم، چون مسیر index route با مسیر پدرش یکیه(وقتی در مسیر parent باشیم، این index route رندر میشه، پس index route ویژگی path نداره.) Index Routeدر برنامه بالا، وقتی در  /  باشیم، صفحه خالیه و داخل تگ &lt;main&gt; چیزی نیست و این یجورایی خوب نیست، بهتره به صورت پیشفرض یه چیزی اون وسط رندر بشه، کافیه یک index route اضافه کنیم:حالا اگر در / باشیم، کامپوننت Activity در Outlet رندر میشه.بخش دهم: Not Found Pageاما چطور میتونیم صفحه 404 بسازیم؟ وقتی که URL با هیچ کدوم از مسیرها جور نیست و میخوایم یک صفحه 404 به کاربر نشون بدیم. =&gt; کافیه یک Route با &quot;*&quot;=path تعریف میکنیم.این مسیر با هر URL ای match میشه اما کمترین اولویت رو داره، یعنی ریکت‌­روتر تنها زمانی این رو انتخاب میکنه که هیچ Route دیگه ای انتخاب نشده باشه.وقتی یک URL وارد بشه و با هیچ کدوم از روت ها، همخونی نداشته باشه، کامپوننت NotFoundPage رندر میشه.=&gt; همانطور که قبلا گفتیم، اینجا ترتیب Route ها مهم نیست. در نسخه قبلی، این صفحه 404 حتما باید به عنوان مسیر آخر قرار داده میشد که اگه کلا هیچ کدوم از بالایی ها انتخاب نشدن، این مسیر انتخاب بشه. اما ریکت‌روتر 6 باهوش تره و نیازی به این کارا نیست:)بخش یازدهم: Passing Data Between Routes– در بحث Dynamic Routing و URL params همون موارد قبلی و هوک useParams رو داریم:useParams Hook=&gt; اما در این نسخه امکان استفاده از optional params (همون ?) و Regex در URL params نیست، در نتیجه ساختار های زیر(فعلا) معتبر نیستن:/users/:id?/tweets/:id(\d+)– در بحث state هم در این نسخه، به جای اینکه به ویژگی to ،یک obj بدیم و داخل اون state رو تعیین کنیم، در کامپوننت &lt;Link&gt; ، در کنار to ، یه prop با نام state اضافه شده که اون مقداری که میخوایم منتقل کنیم رو داخل این ویژگی قرار میدیم.همچنین همونطور که قبلا هم گفتیم، در نسخه قبلی از history.push(obj) استفاده میکردیم، اما اینجا از navigate استفاده میکنیم و به عنوان آرگومان دوم یک optionObj داریم که ویژگی state داره:حالا در روت مقصد چطور به این state ای که ارسال کردیم دسترسی داشته باشیم؟ خیلی ساده با استفاده از هوک useLocation :نکته: مقدار state که میفرستیم، serialize میشه، پس نمیتونیم داده های non-serializable مثل تابع، promise و... رو بفرستیم، در این صورت مقدار state که دریافت میشه null خواهد بود.خب تقریبا همه موارد رو بررسی کردیم، تغییرات این نسخه به صورت خلاصه میشه موارد زیر:- حذف ویژگی exact- حذف withRouter- حذف Switch و اضافه شدن Routes- حذف component &amp; render props و اضافه شدن element به جای اونها- حذف history و اضافه شدن هوک useNavigate- حذف Redirect و اضافه شدن Navigate- عدم امکان استفاده از regex در url params و همینطور optional params- باهوش تر شدن ریکت‌روتر در انتخاب مسیر مناسب و عدم نیاز به رعایت ترتیب خاصی در چیدن Route ها- اضافه شدن Outlet و امکان استفاده از Nested Route ها- حذف activeClassName و activeStyle در &lt;NavLink&gt;هوک‌ها و موارد دیگه‌ای هم اضافه شدن که میتونید اونها رو در مستندات خود ریکت‌روتر بررسی کنید.سعی کردم در این دو پست، تغییرات و ویژگی های نسخه جدید React Router رو بررسی کنم، امیدوارم استفاده کرده باشید و مفید بوده باشه.ممنون که وقت گذاشتید و مطالعه کردید.</description>
                <category>Hasan</category>
                <author>Hasan</author>
                <pubDate>Sun, 21 Nov 2021 20:13:37 +0330</pubDate>
            </item>
                    <item>
                <title>تغییرات و ویژگی‌های جدید 6 React Router - قسمت اول</title>
                <link>https://virgool.io/@Hasan-Mir/react-router-v6-part1-evb33if5swm5</link>
                <description>React Router v6به نام خداسلامدر این پست میخوایم به بررسی تغییرات و ویژگی های نسخه جدید React Router یعنی نسخه 6 بپردازیم.یکی از نکات مثبت این نسخه، مستندات بهتر و ظاهر تر و تمیزتر وبسایت ReactRouter.com هست که واقعا نسبت به نسخه 5 خیلی بهتر شده.بخش اول: BrowserRouter &amp; Routes &amp; Routeدر این نسخه همچنان همون BrowserRouter رو داریم و تغییری نکرده.=&gt; اما در این نسخه خبری از Switch نیست، به جای اون کامپوننت Routes رو داریم، که داخل BrowserRouter قرار میگیره و همه Route ها حتما باید داخل این Routes قرار بگیرن.=&gt; در این نسخه در &lt;Route&gt; ،خبری از props های component و render نیست، کامپوننتی که باید رندر بشه رو به صورت JSX به element میدیم. اگر به صورت element={HomePage} بنویسیم غلطه، حتما باید به صورت JSX یعنی &lt;/HomePage&gt; باشه.=&gt; در نسخه 5 ما باید Route ها رو به یه ترتیب خاصی(جزء به کل) قرار میدادیم تا به درستی رندر بشه، اما در این نسخه، ترتیب Route ها مهم نیست و خودش اونی که دقیق تره و بیشتر با آدرس match میشه رو انتخاب میکنه. مثلا اگر آدرس /teams/new باشه، به هر دو مسیر زیر میخوره:اما ریکت روتر همون teams/new رو انتخاب میکنه، چون دقیق تر از /teams/:teamId هست و بیشتر match میشه. در نسخه قبلی حتما باید ترتیب روت ها برعکس می‌بود تا درست رندر میشد.=&gt; با توجه به نکته بالا احتمالا متوجه شدید که در این نسخه دیگه خبری از exact نیست. ریکت‌روتر اونقدر درک و فهم داره که اون مسیری که دقیق‌تر match بشه رو انتخاب کنه.اما یه نکته:اگر بخوایم اون ساختار قبلی رو داشته باشیم که اگر URL با مقدار path ای که به &lt;Route&gt; دادیم شروع شده بود، یعنی اگر url.startsWith(path) مقدارش true بود، Route انتخاب بشه و رندر بشه، چیکار کنیم؟کافیه از “*” در انتهای path استفاده کنیم.در این حالت، اگر بعد از /profile هر چیزی داشته باشیم، مثلا /profile/abcd/13 ، باز هم کامپوننت ProfilePage رندر میشه.همچنین توجه کنید که این  &quot;*&quot; فقط در انتهای path قابل قبوله و حتما بعد از  /  میاد، در نتیجه دو تا ساختار زیر معتبر نیستن:/files/*/cat.jpg/files-*بخش دوم: Navigation Between Routesدر این نسخه، همچنان در خدمت &lt;Link&gt; هستیم برای این منظور که لینک هایی داشته باشیم و با کلیک کردن روی اونها وارد مسیر دیگه‌ای بشیم.برای imperative navigation یا programmatic navigation یعنی همون حالتی که بخوایم مثلا بعد از اینکه یک event رخ داد، یک فرم submit شد، یک درخواست ajax انجام شد و... وارد یک روت دیگه بشیم، در نسخه 5 از history.push یا history.replace استفاده میکردیم.=&gt; اما در این نسخه خبری از history نیست. اینجا از هوک useNavigate استفاده میکنیم.این حالت کار همون history.push رو انجام میده، اما برای history.replace چی داریم؟ تابع navigate به عنوان آرگومان دوم یک شیء میگیره و یک ویژگی replace که مقدارش رو true میدیم. با اینکار یک مسیری رو replace میکنیم، یعنی مسیر فعلی رو جایگزین کنیم نه اینکه مسیر جدیدی رو به session history اضافه کنیم، در این حالت با دکمه برگشت مرورگر، نمیتونیم برگردیم به مسیر قبلی.بخش سوم: Active Link - NavLinkدر لینک های بالای سایت یا همون nav links، وقتی روی یک لینک کلیک میکنیم و وارد صفحه‌ش میشیم، معمولا میخوایم اون لینک(اون لینکی که فعال یا active هست) یک استایل خاص بگیره، برای این کار از &lt;NavLink&gt; استفاده میکنیم.=&gt; در این نسخه خبری از ویژگی های activeClassName و activeStyle نیست. به جای اونها، className و style یک تابع میگیرن که ورودیش یک شیء با ویژگی isActive هست، براساس true یا false بودن این مقدار میتونیم یک style obj یا class name رو return کنیم تا لینکِ فعال، ظاهر متفاوت داشته باشه.اگر URL ،برابرِ مقدار to ِ این &lt;NavLink&gt; باشه، isActive مقدارش true هست، در غیر این صورت، false میشه.بخش چهارم: Relative Linkاون &lt;Link&gt; هایی که مقدار to اونها با / شروع نمیشه، آدرس­شون نسبی هست، نسبت به مسیری که در اون قرار دارن و اون مسیر به صورت خودکار به ابتدای آدرس اونها اضافه میشه:در مثال بالا دو تا لینک داخل کامپوننت Dashboard داریم که آدرسشون نسبی هست(چون با / شروع نشدن) کامپوننت Dashboard در مسیر /dashboard رندر میشه، پس این دو تا لینک مسیرشون میشه/dashboard/invoices و /dashboard/team ، چون داخل کامپوننت Dashboard قرار دارن.=&gt; این قابلیت خیلی خوبه چون اگر url ِ اون parent route رو یه روزی تغییر بکنه، اینها هم به صورت خودکار تغییر میکنن. مثلا اگر آدرسی که کامپوننت Dashboard در اون رندر میشه رو به /dash تغییر بدیم، اون دو تا لینک هم به /dash/invoices و /dash/team تغییر میکنن.بخش پنجم: Redirect - Navigateدر نسخه 5 برای redirect کردن از کامپوننت &lt;Redirect&gt; داخل Route استفاده میکردیم:=&gt; در این نسخه از کامپوننت &lt;Navigate&gt; استفاده میکنیم و اون رو به عنوان  element  به Route میدیم و مسیری که میخوایم به اون redirect بشه رو به ویژگی to اون میدیم:یعنی اگر کاربر مسیر /blogsPage رو وارد کرد، به صورت خودکار به /blogs هدایت میشه و url به /blogs تغییر میکنه.در این حالت با اضافه کردن ویژگی replace ،بهش میگیم این مسیر جدید رو جایگزین اون چه که کاربر وارد کرده کن، اگر اون رو اضافه نکنیم، یک entry جدید به session history اضافه میشه و البته دکمه برگشت به عقب مرورگر هم به یه مشکل ریزی ممکنه بربخوره و کار نکنه:)بخش ششم: Nested Routes &amp; Outletدر این نسخه &lt;Route&gt; ها میتونن داخل هم قرار بگیرن و path هاشون به صورت نسبی و ادامه path ای که Route پدرشون داره در نظر گرفته میشه. یعنی چی؟در نسخه قبلی وقتی مثلا یک صفحه /blogs داشتیم و میخواستیم یک مسیر دیگه به صورت /blogs/:blogId داشته باشیم که یک کامپوننت دیگه داخل کامپوننت پدر رندر میشد، یک Route دیگه داخل خود کامپوننت صفحه /blogs ایجاد میکردیم که مثلا جزئیات پست داخل اون رندر بشه، اما اینجا کافیه اون &lt;Route&gt; رو جایی که داریم روت ها رو تعریف میکنیم، داخل &lt;Route&gt; ِپدرش قرار بدیم.گفتیم که path نسبی هست، یعنی آدرس parent route به صورت خودکار به ابتدای child route اضافه میشه و  نباید  /blogs  رو بنویسیم، فقط قسمت :blogId رو مینویسیم، بدون / قبلش :در این حالت، وقتی URL مثلا /blogs/1234 هست، component tree و اونچه که در خروجی داریم،چنین چیزی هست:و این یعنی داخل کامپوننت BlogPage باید کامپوننت Blog رو رندر کنیم. ولی خب چطور مشخص کنیم کامپوننت Blog در کدوم قسمت BlogPage باید رندر بشه؟ =&gt; در این نسخه با کامپوننت Outlet این کار رو میکنیم. وقتی url با مسیر Child Route یکی بشه، هر جا که Outlet قرار گرفته باشه، nested route مورد نظر رندر میشه:در کد بالا، وقتی URL مثلا /blogs/1234 باشه، کامپوننت Blog بعد از &lt;h2&gt;Blogs Page&lt;/h2&gt; رندر میشه.یک مثال دیگه از مستندات خود ریکت‌روتر:پایان قسمت اولامیدوارم مفید بوده باشه=&gt; قسمت دوم</description>
                <category>Hasan</category>
                <author>Hasan</author>
                <pubDate>Sun, 21 Nov 2021 13:24:11 +0330</pubDate>
            </item>
            </channel>
</rss>