<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های جلال حامد</title>
        <link>https://virgool.io/feed/@iamjalalhamed</link>
        <description>توسعه دهنده فرانت‌اند</description>
        <language>fa</language>
        <pubDate>2026-06-21 04:11:20</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/238745/avatar/B83bdj.jpg?height=120&amp;width=120</url>
            <title>جلال حامد</title>
            <link>https://virgool.io/@iamjalalhamed</link>
        </image>

                    <item>
                <title>ری‌اکت کامپایلر</title>
                <link>https://virgool.io/codenevis/%D8%B1%DB%8C-%D8%A7%DA%A9%D8%AA-%DA%A9%D8%A7%D9%85%D9%BE%D8%A7%DB%8C%D9%84%D8%B1-os2aopihhusb</link>
                <description>دوبله فارسی مقاله ری‌اکت کامپایلر. که بخشی از مقاله ری‌اکت لبز امساله. ری‌اکت لبز مقاله‌ایه که تیم ری‌اکت به صورت سالیانه منتشر میکنه و توش درمورد کارایی که انجام داده و داره انجام میده توضیح میده. آدرس اصل مقاله: react.dev/blog اولین آیتم.تاریخ انتشار 15 فوریه 2024 (26 بهمن 1402)لینک ویدیو اینستاگرام همین مقاله (برای گوش دادن بصورت پادکست)ری‌اکت کامپایلرری‌اکت کامپایلر دیگه یه پروژه تحقیقاتی نیست: الان از کامپایلر توی محیط پروداکشنِ instagram.com استفاده میشه (نسخه وب)، و داریم سعی میکنیم کامپایلر رو به اپلیکیشن‌های دیگه Meta هم منتقل کنیم و اولین انتشار open-sourceاش رو آماده کنیم.وقتی که state تغییر میکنه، ری‌اکت گاهاً میتونه خیلی re-render انجام بده. از همون روزای اولی که ری‌اکت اومد راه‌حال ما برای همچین مواردی، مِموئیزِیشِن دستی بوده. یعنی استفاده از APIهای useMemo، useCallback و memo برای تنظیم دستی میزان re-render ری‌اکت به هنگام تغییر state. اما مِموئیزِیشِن دستی خطریه. موجب درهم‌ریختگی کد میشه، به راحتی میشه اشتباه پیاده‌سازیش کرد، و بروزنگه‌داشتنش هم کار اضافه میطلبه.مِموئیزِیشِن دستی یه خطر منطقیه، ولی ما راضی نبودیم. چشم‌انداز ما برای ری‌اکت اینه که بدون به‌خطر انداختن مدل ذهنی اصلی ری‌اکت، وقتی که state تغییر کرد، خودش به شکل اتومات قسمت‌های لازم رو توی UI ری‌رندر کنه. — خرد کردن UI به فاکنش‌های ‌ساده‌ای که هرکدوم state مخصوص خودشون رو دارن، با همه مقادیر و اصطلاحات استاندارد جاوااسکریپتی — ما براین باور هستیم که این رویکرد ری‌اکت یکی از مهمترین دلایلیه که توسط این همه دولوپر پذیرفته شده و داره ازش استفاده میشه. واسه همینه که روی ساخت یه کامپایلر بهینه‌ساز سرمایه‌گذاری کردیم.جاوااسکریپت به خاطر قوانین شل و ول و ماهیت پویا و متغیری که داره، برای بهینه‌سازی، زبان چالش‌برانگیزی محسوب میشه. ری‌اکت کامپایلر میتونه با مدل‌سازی همزمان قوانین جاوااسکریپت و &quot;قوانین ری‌اکت&quot;، کد رو به طور ایمن کامپایل کنه. مثلاً کامپوننت‌های ری‌اکت باید ایدمپوتنت باشند، — یعنی با دادن ورودی‌های یکسان، همواره باید مقدار یکسانی رو برگردونن — و نمی‌تونن مقادیر props یا state رو تغییر بدن. این قوانین با محدود کردن دولوپرها کمک میکنه که یه فضای امن برای کامپایلر ایجاد بشه که بتونه به‌درستی بهینه‌سازیش رو انجام بده.البته ما میدونیم که دولوپرها گاهی یکم قوانین رو تغییر میدن، و هدفمون هم اینه که کامپایلر ری‌اکت بتونه از همون اول روی اکثر کدها کار کنه. کامپایلر سعی میکنه تشخیص بده که چه زمانی کد دقیقاً از قوانین ری‌اکت پیروی نمیکنه و اون موقع یا کد رو جایی که امنه کامپایل میکنه یا اگه ایمن نباشه از کامپایل صرف نظر میکنه. ما در حال تست کردن این رویکرد روی codebase بزرگ و متنوع متا هستیم تا به اعتبار این رویکرد کمک کنیم.برای دولوپرهایی که میخوان مطمئن بشن کدشون با قوانین ری‌اکت سازگاری داره، توصیه میکنیم حالت Strict Mode رو فعال کنن و پلاگینESLint  عه ری‌اکت رو روی کدشون کانفیگ کنن. این ابزارها می‌تونن به شناسایی باگ‌های ظریف توی کد ری‌اکت شما کمک کنند، کیفیت برنامه‌های شما را همین امروز بهتر میکنن و برنامه‌های شما را برای ویژگی‌های آینده مثل کامپایلر ری‌اکت آماده می‌کنن. ما همچنین داریم روی مستندات تجمیعی از قوانین ری‌اکت و آپدیت‌های افزونه ESLintمون کار میکنیم تا به تیم‌ها کمک کنیم این قوانین رو برای ایجاد برنامه‌های قوی‌تر درک و اعمال کنند.برای اینکه عملکرد کامپایلر رو ببینید میتونید صبحت پاییز پارسالمون رو ببینید (پاییز میلادی). اون موقع ما یه سری اطلاعات تجربی اولیه از امتحان کردن React Compiler روی یکی از صفحات instagram.com داشتیم. از اون موقع، از کامپایلر داریم روی محیط پروداکشن instargram.com استفاده می‌کنیم. همچنین برای تسریع توضیع به بقیه محیط های Meta و پروژه های open source، تیممون رو هم بزرگتر کردیم. درمورد مسیر پیش‌ رو هیجان‌زده‌ایم و در ماه‌های آینده چیزای بیشتری برای به اشتراک گذاری خواهیم داشت.</description>
                <category>جلال حامد</category>
                <author>جلال حامد</author>
                <pubDate>Fri, 12 Apr 2024 16:53:05 +0330</pubDate>
            </item>
                    <item>
                <title>جاوا اسکریپت بجای HTML با یک مثال ساده</title>
                <link>https://virgool.io/@iamjalalhamed/%D8%AC%D8%A7%D9%88%D8%A7-%D8%A7%D8%B3%DA%A9%D8%B1%DB%8C%D9%BE%D8%AA-%D8%A8%D8%AC%D8%A7%DB%8C-html-%D8%A8%D8%A7-%DB%8C%DA%A9-%D9%85%D8%AB%D8%A7%D9%84-%D8%B3%D8%A7%D8%AF%D9%87-myohpdiq2tyr</link>
                <description>نمایش دادن &quot;Hello World&quot; روی یک صفحه وب زیاد طول نمی‌کشه. کافیه یه فایل html. درست کنید و این محتویات رو بریزید توش:&lt;html&gt;
    &lt;body&gt;
        &lt;div&gt;Hello World&lt;/div&gt;
    &lt;/body&gt;
&lt;/html&gt;حالا اون فایل رو با هر مرورگری که دوست دارید باز کنید و بوم! تبریک.ولی اولین چالشتون یحتمل وقتی بوجود میاد که تصمیم می‌گیرید مثلاً وقتی روی همون متنِ &quot;Hello World&quot; ای که توی پاراگراف قبلی ساختیمش کلیک شد، متن عوض بشه و یه جمله جدید بهمون بده. مثلاً تغییر کنه به &quot;You Clicked Me&quot;.خب برای اینکار لازمه که از یه زبان برنامه‌نویسی استفاده کنیم (HTML که مخففِ Hyper Text Markup Language هست، همونطور که از اسمش برمیاد، زبان نشانه گذاریه). و برای اینکار زبان جاوا اسکریپت رو داریم. مرورگر شما، کد HTML ای که نوشتید رو توسط یک موتور مخصوص (مثلاً اگر از chrome استفاده می‌کنید موتور V8) به شکل یک Object درمیاره و به جاوا اسکریپت تحویل میده. که اون Object رو بهش میگیم DOM (مخفف Document Object Model). اینطوری جاوا اسکریپت می‌تونه با کد HTML تون تعامل کنه؛ مثلاً‌ بهش node های جدیدی اضافه یا کم کنه. یا حتی محتوایات و ویژگی های node های فعلی رو عوض کنه. (توی جاوا اسکریپت به المان های HTML میگیم nodes و یا به طور کامل تر DOM nodes).پس برای دسترسی به Hello World توی مثالمون و تغییر دادن متنش وقتی که رویداد کلیک اتفاق افتاد، کافیه که از جاوا اسکریپت و توابع از پیش تعریف شده ای که برای دستکاری DOM توی خودش داره استفاده کنیم. دسترسی به node ها با تعریف کردنِ ویژگیِ id واسشون خیلی ساده تر میشه:&lt;div id=&amp;quotgreet&amp;quot&gt;Hello World&lt;/div&gt;بعد می‌تونیم توی خط بعدی از تگ  برای ورود به دنیای جاوا اسکریپت، و برنامه نویسیِ تغییر جمله در پاسخ به رویداد کلیک، استفاده کنیم:
    let greetElement = document.getElementById(&amp;quotgreet&amp;quot);
    greetElement.addEventListener(&amp;quotclick&amp;quot, () =&gt; {
        return greetElement.textContent = &amp;quotYou Clicked Me&amp;quot
    });
پس نهایتاً نمای کلیِ فایلمون اینطوری میشه:&lt;html&gt;
    &lt;body&gt;
        &lt;div id=&amp;quotgreet&amp;quot&gt;Hello World&lt;/div&gt;
        
            let greetElement = document.getElementById(&amp;quotgreet&amp;quot);     
            greetElement.addEventListener(&amp;quotclick&amp;quot, () =&gt; {
                return greetElement.textContent = &amp;quotYou Clicked Me&amp;quot     
            }); 
        
    &lt;/body&gt;
&lt;/html&gt;حتی می‌تونیم تگ div با id ی greet و مقدار اولیهٔ Hello World رو هم با جاوا اسکریپت تولید و روی صفحه نمایش بدیم:&lt;html&gt;
     &lt;body&gt;
         
             let greetElement = document.createElement(&amp;quotdiv&amp;quot);
             greetElement.textContent = &amp;quotHello World&amp;quot
             document.body.append(greetElement);
             greetElement.addEventListener(&amp;quotclick&amp;quot, () =&gt; {
                 return greetElement.textContent = &amp;quotYou Clicked Me&amp;quot
             });
          
     &lt;/body&gt;
&lt;/html&gt;بعد از ذخیره کردن، کافیه این فایل رو با هر مرورگری که می‌خواید باز کنید. روی صفحه Hello World خواهید دید که اگه روش کلیک کنید به You Clicked Me تغییر پیدا میکنه.</description>
                <category>جلال حامد</category>
                <author>جلال حامد</author>
                <pubDate>Fri, 24 Sep 2021 13:49:09 +0330</pubDate>
            </item>
                    <item>
                <title>واژه نامهٔ ری‌اکت ۱۸ — یه جوری توضیح بده انگار ۵ سالمه..</title>
                <link>https://virgool.io/@iamjalalhamed/%D9%88%D8%A7%DA%98%D9%87-%D9%86%D8%A7%D9%85%D9%87%D9%94-%D8%B1%DB%8C-%D8%A7%DA%A9%D8%AA-%DB%B1%DB%B8-%DB%8C%D9%87-%D8%AC%D9%88%D8%B1%DB%8C-%D8%AA%D9%88%D8%B6%DB%8C%D8%AD-%D8%A8%D8%AF%D9%87-%D8%A7%D9%86%DA%AF%D8%A7%D8%B1-%DB%B5-%D8%B3%D8%A7%D9%84%D9%85%D9%87-haaviyzq9xkv</link>
                <description>حدود ۴ ماه پیش یه گفت‌وگو [discussion] جدید توی ریپازیتوریِ ری‌اکت ۱۸ متعلق به reactwg (wg مخفف working group) باز شد و sylwiavargas که آغاز کنندهٔ این گفت‌و‌گو بود، عنوان گفت‌و‌گو رو گذاشت &quot;واژه نامه + یه جوری توضیح بده انگار ۵ سالمه&quot; و توی پیامِ اولش نوشت &quot;...برای پیدا کردن (یا اضافه کردن) یه اصطلاح یا توضیح جدید به قسمت نظرات برید... بیاید به توسعه دهنده های جدید ری‌اکت کمک کنیم به اندازهٔ ما از این release هیجان‌زده بشن!&quot; قرار بر این بود که هر کسی اصطلاحی از ویژگی های ری‌اکت ۱۸ شنیده که معنی و یا کارآییش رو درست متوجه نشده، اون رو توی قسمت نظرات بپرسه تا تیم ری‌اکت به کمک ساده ترین مثال های ممکن اون رو برای همه توضیح بده. هرچند سوال ها بعد از مدت کوتاهی دیگه به ری‌اکت ۱۸ محدود نمی‌شدن و سوالاتی دربارهٔ ویژگی‌هایی فراتر از ری‌اکت ۱۸ و حتی ویژگی های کاملاً بنیادین ری‌اکت (render کردن چیه؟ توضیح دقیق state ها چیه؟ ...) پرسیده و پاسخ داده شدن.این صرفاً یک ترجمه است. می‌تونید متن اصلی رو با کلیک کردن روی این لینک پیدا کنید.همزمانی [CONCURRENCY]نویسنده: gaearonهمزمانی به این معناست که تسک ها می‌تونن با هم تداخل کنن (روی هم بیوفتن).مثلاً می‌تونیم از تماس های تلفنی به عنوان قیاس استفاده کنیم.غیرهمزمانی یعنی من در آنِ واحد فقط می‌تونم یک مکالمهٔ تلفنی داشته باشم. اگه دارم با آلیس حرف می‌زنم، و یهو باب بهم زنگ می‌زنه، اول باید تماسم رو با آلیس تموم کنم و بعد می‌تونم با باب حرف بزنم.همزمانی یعنی می‌تونم در آنِ واحد بیشتر از یک مکالمه داشته باشم. مثلاً می‌تونم آلیس رو بذارم رو ‌hold، یکم با باب صحبت کنم، و بعد دوباره برگردم به تماسم با آلیس.توجه کنید که همزمانی لزوماً به این معنا نیست که با دو نفر در آنِ واحد حرف بزنم. فقط به این معناس که در هر لحظه ای، ممکنه وسط چند تا تماس باشم، و می‌تونم مثلاً بر اساس اینکه کدوم مکالمه ضروری تره، انتخاب کنم که با کی حرف بزنم.حالا برای اینکه این قیاسمون رو ترجمه کنیم، توی ری‌اکت &quot;تماس های تلفنی&quot; میشن همون کال های &quot;setState&quot;. قبلاً ری‌اکت در آنِ واحد فقط می‌تونست روی یک آپدیتِ state کار کنه. پس همهٔ آپدیت ها &quot;ضروری&quot; بودن: همین که شروع می‌کردید به re-render کردن، دیگه نمی‌تونستید متوقف بشید. اما  با startTransition می‌تونید یه آپدیت غیرضروری رو به عنوان یه transition علامت بزنید.می‌تونید آپدیت های &quot;ضروری&quot; setState رو معادل همون تماس های تلفنیِ ضروری ببینید (مثلاً دوست‌تون به کمک‌تون نیاز داره) در حالی که transition ها مثل مکالمه های ریلکسی هستن که می‌تونن برن رو hold یا حتی قطع بشن اگه دیگه مطابقت نداشتن.تعلیق [SUSPENSE]نویسنده: sylwiavargas‌#۲۸ یه thread بسیار کارآمده که توش دو تا قیاسِ اساسی واسه تعلیق [suspense] داره:قیاسِ Skn0tt@:یه کامپوننت رو تصور کنین که قبل از اینکه render بشه باید یه سری تسک های ناهمزمان [asynchronous] رو انجام بده، مثلاً یه سری داده fetch کنه.قبل از تعلیق، یه همچین کامپوننتی state یه isLoading رو نگه می‌داشت و بر اساس اون یه جور fallback رو return می‌کرد (مثلاً یه state خالی، اسکلت‌بندی، اسپینر، ...).با تشکر از تعلیق، حالا یه کامپوننت می‌تونه در حین render شدن داد بزنه &quot;حاجی وایسا! من هنوز آماده نیستم. من رو render نکن فعلاُ بی زحمت - هر وقت آماده بودم صدات می‌کنم!&quot;اینجا ری‌اکت میره نزدیک‌ترین تعلیقی که توسط شما set شده و شامل fallback هست رو پیدا می‌کنه و تا زمانی که اون کامپوننت آمادگی خودش رو جهت render شدن اعلام کنه، اون رو render می‌کنه.قیاسِ gaearon@:یه راه دیگه واسه توضیح دادنش، اینه که داستان مثل - پرتاب کردن / گرفتن - می‌مونه ولی در جهت لود کردن state ها. وقتی یه کامپوننت میگه &quot;من آماده نیستم&quot; (یه موقعیت غیرمعمول، مثل پرتاب کردن)، نزدیک ترین بلوکِ تعلیقِ بالا (مثل گرفتن) میاد بجاش اون fallback رو نشون میده. بعد، وقتی که وعده [promise] حل شد [resolve]، ما یه &quot;تلاش مجدد&quot; می‌کنم واسه render کردن.یه تفاوت کلیدی که توی برنامه نویسی بر پایه ی وعده [Promise-based programming] ی مرسوم وجود داره اینه که وعده ها [Promises] در معرض کد کاربر نبودن. شما مستقیماً باهاشون سر و کله نمی‌زدید. شما Promise.all یا then. یا یه همچین کارایی باهاشون نمی‌کردید. بجای &quot;صبر کن تا وعده [promise] حل [resolve] بشه و یه سری از کد های کاربر رو اجرا کن&quot;، الگو اینطوری میشه که &quot;ری‌اکت وقتی resolve شد خودش دوباره فرایند render کردن رو اجرا می‌کنه&quot;. از بعضی جهات این ساده تره ولی یه مقدار &quot;یاد نگرفتن&quot; می‌خواد چون کاربر یه مقدار از کنترلی که از سر برنامه نویسی بر پایه وعدهٔ مرسوم بهش عادت کرده بوده رو از دست میده.دسته‌بندی و دسته‌بندیِ اوتوماتیک[BATCHING AND AUTOMATIC BATCHING]نویسنده: gaearonدسته‌بندی [Batching]تصور کنید دارید صبحانه آماده می‌کنید.میرید سوپرمارکت تا یکم شیر بخرید. برمی‌گردید. بعد متوجه می‌شید یه مقدار کورن فلکس لازم دارید. میرید سوپرمارکت تا کورن فلکس بخرید. بعد برمی‌گردید. بعد متوجه می‌شید که بیسکویت لازم دارید. میرید سوپرمارکت و بیسکویت می‌خرید. بالاخره، می‌تونید صبحانه تون رو میل کنید.ولی مطمئناً یه راه مؤثرتر واسه انجامش هست نه؟ بجای اینکه هر مورد رو به محض اینکه به ذهنتون رسید برید بخرید و بیاید، ایدهٔ‌ بهتر اینکه اول یه لیست خرید تهیه کنید. بعد برید سوپرمارکت و همه چیزهایی که لازم دارید رو بخرید و صبحانه تون رو حاضر کنید.این میشه دسته‌بندی [batching].توی ری‌اکت، هر موردِ مجزا، یه کالِ setState هست.setIsFetching(false);
setError(null);
setFormStatus(&#039;success&#039;)ری‌اکت می‌تونست بعد از هر کدوم از این call ها، (&quot;برو به مغازه&quot;) رو دوباره render کنه (re-render کنه). ولی چنین حرکتی کارآمد نیست. بهتر اینه که اول همه ی آپدیت های state رو ذخیره کنه و بعد، وقتی همهٔ اون قسمتایی از state رو که می‌خواستید آپدیت کردید، یک بار re-render کنه.چالشش اینجاست که ری‌اکت چه زمانی باید اینکارو انجام بده. از کجا می‌تونه بفهمه کارتون با آپدیت کردن state تموم شده؟برای event handler ها که آسونه:function handleClick() {
    setIsFetching(false);
    setError(false);
    setFormStatus(&#039;success&#039;);
}ری‌اکت اون چیزه که click handler شما رو call می‌کنه.// l :توی ری‌اکت
handleClick();پس ری‌اکت بلافاصله بعدش فرایند re-render رو اجرا می‌کنه:// l :توی ری‌اکت
handleClick();
updateScreen();ری‌اکت اینطوری کار می‌کرد همیشه.دسته‌بندیِ اوتوماتیک [Automatic batching]برگردیم به این مثال:setIsFetching(false);
setError(null);
setFormStatus(&#039;success&#039;);اگه در جریان یه event اتفاق نیوفته چی؟ مثلاً، شاید این کد بعد از یه run ،fetch بشه. ری‌اکت هیچ ایده ای نداره که کِی state set کردن شما &quot;تموم&quot; میشه. پس باید یکم زمان بذاره تا صفحه رو آپدیت کنه.این مشابه اینه که شما صبحونه نخورید و بجاش تمام روز هوس های اَلا بختکی داشته باشید. آیا همون لحظه که احساس گرسنگی می‌کنید میرید سوپرمارکت؟ یا یه مدت صبر می‌کنید (مثلاً ۳۰ دقیقه) و بعد با لیست چیزهایی که میخواستید بخرید میرید سوپرمارکت؟قبلاً، ری‌اکت اینطوری بود که در چنین موقعیتی بلافاصله re-render می‌کرد. یعنی بابت ۳ بار setState رو صدا زدن، ۳ تا آپدیتِ صفحه گیرتون میومد. این زیاد کارآمد نیست.با دسته‌بندی اوتومات شده [automated batching] توی ری‌اکت ۱۸، اینا همیشه دسته‌بندی [batch] میشن. عملاً به این معناست که ری‌اکت &quot;یکم صبر می‌کنه&quot; (اصطلاح فنی‌اش میشه &quot;تا آخره تسک یا ریزتسک [microtask]). بعد ری‌اکت صفحه رو آپدیت می‌کنه.آب‌رسانی [HYDRATION]نویسنده: sylwiavargasتوضیح دَن از آب‌رسانی توی ۳۷# (با زیرعنوان &quot;SSR چیست؟&quot;) مفهوم رو می‌رسونه. اینم یه گزیده‌ اش:پروسهٔ render کردن کامپوننت هاتون و پیوستن event handler ها به اونا به عنوان &quot;آب‌رسانی&quot; شناخته میشه. مثل این میمونه که یه HTML &quot;خشک&quot;، از &quot;آب&quot; عه فعل و انفعال داشتن و event handler ها سیراب بشه.از توییتِ Bruno Nardini:قیاسی که دوست دارم برای &quot;آب‌رسانی&quot; بکار ببرم اینه که به طور خشک load میشه، و بعد به چرخ‌دنده ها روغن زده میشه تا حرکتش بدن. نویسنده: meganesuچیزی که من فهمیدم:آب‌رسانی فقط با render شدن سمت سرور [server-side rendering] استفاده میشه.وقتی از ‌SSR استفاده می‌کنید، پروسهٔ render کردن کامپوننت ها توی مرورگرتون شامل ۲ تا مرحله میشه:اون HTML و CSS غیرتعاملی [non-interactive] و render شد در سمت سرور فرستاده میشن به مرورگر. اینطوری کاربرتون در حالی که منتظره جاوا اسکریپت صفحه تون load بشه یه چیزی برای دیدن داره.وقتی جاوا اسکریپتتون load شد HTML و CSS &quot;آب‌رسانی&quot; میشن، که بعد کاربر می‌تونه با چیزهایی که روی صفحه تون هست تعامل داشته باشه. (روی دکمه ها کلیک کنه، dropdown هارو باز و بسته کنه، غیره).رِندِر سمت سرور [SSR]نویسنده: laurieontechمیشه SSR رو به خوبی با غذا توضیح داد.فرض کنید به یه میز سالاد رفتید و می‌تونید همه ی اجزائی که می‌خواید رو از روش بردارید تا سالاد خودتون رو درست کنید. شما اونارو با هم مخلوط می‌کنید، اونطوری که دلتون می‌خواد طبقه‌بندیش می‌کنید، و بعد اون رو میل می‌کنید. این میشه render سمت کلاینت [client-side rendering]. شما اجزاء رو در کنار هم قرار می‌دید (JS ،CSS ،HTML‌، خودتون).از اون طرف می‌تونید به یه میز سالاد برید و یه سالادِ از قبل آماده شده رو بردارید. اون آماده است، تمام کاری که لازمه بکنید اینه که اون رو میل کنید. این میشه render سمت سرور [server-side rendering]. شما یه HTML آماده ی render رو مستقیماً از سرور دریافت می‌کنید.نویسنده: sophiebitsغالب مردم فکر می‌کنند ری‌اکت سمت کلاینت run میشه (مثلاً توی مرورگر کاربر). نتیجه render شدن کامپوننت ها میشه تغییر دادن HTML ای که روی صفحه هست. وقتی یه کاربر وارد وب‌سایتی میشه که از ری‌اکت استفاده می‌کنه، اول باید ری‌اکت و کد جاوا اسکریپتی که برای هر کامپوننت ری‌اکت استفاده شده رو دانلود کنیم، و بعد روی مرورگرشون اون کد رو run می‌کنیم تا ببینیم چه HTML ای رو می‌خوایم روی صفحه نشون بدیم. وقتی این اتفاق افتاد، کاربر می‌تونه app رو ببینه و باهاش تعامل کنه.رِندِر سمت سرور [server-side rendering] وسیله ایه که به طراحی شده تا به اون پروسه سرعت ببخشه تا که صفحه بتونه از load ری‌اکت سریعتر استفاده کنه. وقتی از SSR استفاده می‌کنیم، ما اول اون کامپوننت هایی که دارن فایل های مورد نیاز صفحه رو برای کاربر می‌فرستن run می‌کنیم. HTML خروجی رو توسط اون کامپوننت ها می‌گیریم و اون HTML رو می‌فرستیم برای صفحه کاربر. همین که اون رسید، کاربر می‌تونه همه محتوای صفحه رو ببینه. حواستون باشه که HTML خودش می‌تونه تصویری از چیزی که قراره صفحه در ابتدا  نشون بده رو بهمون بده و به خودیه خود تعامل پذیر نیست. پس همچنان لازمه که کد ری‌اکت و جاوا اسکریپتِ هر کامپوننت ری‌اکت رو دانلود کنیم، و بعد باید به ری‌اکت بگیم که اون HTML ای که قبلاً روی صفحه بوده رو &quot;کنترل کن&quot;، که بهش میگن &quot;آب‌رسانی&quot;. وقتی اون تموم شد، کاربر می‌تونه همه محتویات صفحه رو ببینه و می‌تونه باهاشون تعامل کنه.اینطوری SSR به نمایان شدن سریعتر صفحهٔ اولیه کمک می‌کنه ولی باعث نمیشه که سریعتر تعاملی [interactive] بشه چون بازم باید منتظر دانلود و run شدنِ همهٔ کد های جاوا اسکریپت بمونید - با SSR، دیگه داریم همه کامپوننت هارو روی سرور run می‌کنیم، ولی در عین حال همچنان داریم اونارو سمت کلاینت run می‌کنیم. (اتفاقی که در آینده برای سرور کامپوننت ها خواهد افتاد - تجربه ای جدید توسط تیم ری‌اکت - اینه که به گونه ای طراحی میشن که شما بتونید بعضی کامپوننت هارو فقط روی سرور run کنید، ولی حالا حالاها بعیده آماده بشه.)برای اینکه از SSR استفاده کنید، باید ۲ تا کار انجام بدید: (الف) مطمئن بشید هر کامپوننت ری‌اکت ای که روی کد بیس‌تون دارید فقط از ویژگی هایی استفاده می‌کنه که هم سمت سرور و هم سمت کلاینت جواب میدن. (یه سری مقررات داره، مثلاً استفاده نکردن از آبجکت window از اونجایی که فقط سمت کلاینت کار می‌کنه)، و (ب) کد سمت سرورتون رو به گونه ای تغییر بدید که ری‌اکت رو call کنه و با HTML ای که در نتیجه برمی‌گرده یه کاری انجام بده. بعضی از فریم‌ورک ها مثل Next.js به طور پیش‌فرض SSR رو ساپورت می‌کنن، که یعنی اونا قسمت (ب) رو واستون انجام دادن.اثرات منفعل [PASSIVE EFFECTS]نویسنده: gaearonدو نوع اثر [effect] داریم:useEffect = &quot;effects&quot;useLayoutEffects = &quot;layout effects&quot;گاهاً وقتی شما می‌گید &quot;effects&quot; معلوم نیست منظورتون هر دو نوع هست یا فقط نوع اول. واسه اینه که نوع اول (useEffect) بعضی وقتا &quot;منفعل&quot; [passive] صدا زده میشه.ما توی داکیومنت ها [docs] همیشه از این لفظ پرهیز می‌کنیم، اما بین خودمون توی مکالمه های اصلی تیم و حتی توی کامنت های GitHub ازش استفاده می‌کنیم. فکر می‌کنم نگه دارندگان کتابخانه [library maintainers] یحتمل از همینجا یادش گرفتن. من انتظار ندارم نویسنده های اپلیکیشن [application authors] راجع به این لفظ بدونن  و یا بهش اهمیت بدن - ولی اگه شما دیدینش، معنیش همون useEffect خودمونه، نه هیچ چیز دیگه ای.رویدادهای گسسته [DISCRETE EVENTS]نویسنده: gaearonرویدادهای &quot;گسسته&quot; مفهومی نیست که ما هیچ کجای داکیومنت ها [docs] ازش استفاده کنیم. مفهومی نیست که انتظار داشته باشیم دولوپر های اپلیکیشن های ری‌اکتی [React application developers] راجع بهش بدونن یا بهش اهمیت بدن.با این حال، وقتی توضیح میدیم که دسته‌بندی اوتوماتیک چطوری کار می‌کنه بحثش پیش میاد. چیزی که لازمه روشن کنیم اینه که برای بعضی رویدادها، مثل کلیک کردن ها، تضمین می‌کنیم که صفحه، قبل از اینکه رویداد بعدی بتونه اجرا بشه، آپدیت میشه. این واسه روابط کاربری ای مثل شمارنده ها [counters] (تصور کنید کاربر دو بار خیلی سریع رو یه دکمه کلیک کنه) یا فرم ها (جایی که فرستادن یک فرم ممکنه باعث غیرفعال شدنش بشه، و اگه این اتفاق قبل از فشار دادن دکمه دوم نیوفته، ریسک ۲ بار فرستادن یک فرم رو متحمل می‌شید) اهمیت داره.چنین رویداد هایی رو &quot;گسسته&quot; می‌نامیم. این به این معناس که هر رویداد به صورت جداگانه ای توسط کاربر در قصد شده. اگه ۲ بار کلیک می‌کنم، بخاطر اینه که می‌خوام ۲ بار کلیک کنم. اگه تایپ می‌کنم &quot;س&quot;، &quot;ل&quot;، &quot;ا&quot;، &quot;م&quot;، بخاطر اینه که می‌خوام تایپ کنم &quot;سلام&quot;. این با رویدادی مثل mousemove (حرک موس) تفاوت داره. من شاید موس رو تو ده جهت مختصاتی مختلف حرکت بدم در حالی که از قصد نمی‌خواستم موس رو توی هیچ‌کدوم از این جهت های مختصاتی مختلف تکون بدم. به عنوان یه کاربر هیچ ایده ای ندارم الان چند بار رویداد mousemove رو اجرا کردم. فقط موس رو تکون دادم. به چنین رویدادهایی میگیم &quot;مداوم&quot; [continuous]. — که توی اینا، آخرین مورد اهمیت داره، نه که چندتا اتفاق افتاد.این مفاهیم فقط برای ساختار درونی ری‌اکت اهمیت داره، چون ممکنه آپدیت هارو طبق چند تا رویداد مداوم [continuous] دسته‌بندی [batch] کنه، ولی بازم به ازای هر رویداد &quot;گسسته&quot; ی پی در پی، صفحه رو آپدیت می‌کنه. به هر ترتیب، به عنوان یه کاربر ری‌اکت، شما یحتمل لازم نباشه بهش فکر کنین.تیک وعده [PROMISE TICK]نویسنده: gaearonیک وعده آبجکتیه که نمایندهٔ چیزیه که در آینده موجود خواهد شد. می‌تونید به وعده [promise] مثل همون تایمر هایی که تو بعضی از رستوران ها بهتون میدن فکر کنید. وقتی تایمرر زنگ میزنه، میرید غذاتون بر برمی‌دارید.let food = await cook();
eat(food);وقتی می‌بیند که توی کد از await استفاده شده، مهمه که متوجه باشید که تابع شما همش با هم اجرا نمی‌شه. بجاش، هر await، تابع شما رو &quot;جدا&quot; [split] می‌کنه (شکاف میده / به دو نیم می‌کنه). یه بخشی هست که قبلش run میشه (اینجا ()cook به شما یه وعده [promise] میده). بعد بهش می‌گید وقتی که غذا آماده شد، ادامه بده. در نهایت، وقتی غذا آماده شد، برمی‌گردید به این تابع، به متغیر food مقدار اولیه میدید، و میلش می‌کنید.یک &quot;تیک وعده&quot; [Promise tick] به زمانی اشاره می‌کنه که جاوا اسکریپت تابع شما رو که منتظر یه وعده بود، ادامه میده. بهش میگن &quot;تیک&quot; چون یه تایمره. وقتی نتیجه آماده است، وعده بلافصله تابع شما رو ادامه نمیده. بجاش به محظ اینکه ممکن بود بعد از اینکه اون کُدی که در اون لحظه در حال اجرا شدنه کارش تموم شد اینکارو انجام میده. می‌تونید به این مثل سرآشپز رستورانی فکر کنید که منتظره دستش آزاد بشه تا &quot;تایمر&quot; شما رو call کنه بجای اینکه به محظ اینکه غذاتون رو آماده کرد اینکارو بکنه.همگام سازیِ فلاش [FLUSH SYNC]فلاش / فلاش کردن می‌تونه به معنای سیفون کشیدن باشه. به طور کلی به معنای منزه کردن هر چیزی می‌تونه به کار بره.    - جلالهمگام سازیِ‌ فلاش اسم روشیه که بهتون اجازه میده کنترل کنید ری‌اکت کِی صفحه رو آپدیت می‌کنه. (آپدیت های state رو &quot;فلاش&quot; می‌کنه). مخصوصاً بهتون این قابلیت رو میده که به ری‌اکت بگید همین الان اینکارو بکنه. (&quot;به طور همزمان&quot; [synchronously])flushSync(() =&gt; {
    setState(something);
});
// به این خط که برسیم، صفحه یه دور آپدیت شده&quot;Flush synchronously&quot; = &quot;همین الان صفحه رو آپدیت کن&quot;معمولاً نباید به flushSync احتیاج پیدا کنید. فقط در صورتی ازش استفاده می‌کنید که بخواید که مشکلی که توش ری‌اکت دیرتر از اون زمانی که شما می‌خواید صفحه رو آپدیت می‌کنه رو برطرف کنید. خیلی به ندرت پیش میاد همچین چیزی.جداسازی کد [CODE SPLITTING]نویسنده: laurieontechمطمئن نیستم این کار مجاز باشه {چون داره روی ریپازیتوریه یکی دیگه تو گیت هاب منتشرش می‌کنه اینو میگ}، ولی یه پست روی وبلاگم نوشتم که توش اینو توضیح دادم.خلاصه اش میشه محدودیتِ کیف و چمدونِ خطوط هوایی. هر چمدون فقط می‌تونه ۵۰ پوند (حدود ۲۲.۶ کیلوگرم) یا کمتر وزن داشته باشه. ولی شما لازمه که ۱۵۰ پوند وسیله با خودتون بیارید مثلاً. پس اونارو توی ۳ تا چمدون پخش می‌کنید که همشون بتونن باهاتون پرواز کنن در حالی که محدودیت رو هم نقض نکردن.نویسنده: shrutikapoor08منم اتفاقاً یه پست در راستای توضیح دادن جداسازی کد نوشتم که اینجاس. اگه خوب بنظر برسه منتشرش می‌کنم. {منظورش یحتمل اینه که بعنوان یه پست روی وبلاگش..}ابطال و کنترل کردن [DEBOUNCING AND THORRLING]  نویسنده: gaearonابطال و کنترل کردن چیه؟ابطال و کنترل کردن برای سر و کله زدن با چیز هایی که &quot;زیادی اتفاق میوفتن&quot; روش های بسیار متداولی هستن. تصور کنید یکی از دوستانتون رو دیدید، و داره براتون یه قصه تعریف می‌کنه، ولی در حین صحبت به سختی مکث می‌کنه. بیایید فرض کنیم قراره یه اقامتگاه هم برای ایشون ردیف کنید در حالی که همچنین پاسخ صحبت هاش رو هم می‌دید، وقتی که ممکن بود. (میدونم یکم تخیلیه، ولی تحملش کنید!) فرض کنیم هیچ‌وقت نمی‌تونید همزمان با هم حرف بزنید / تو حرف هم بپرید. حالا شما چند تا استراتژی دارید:همزمانی [Synchronous]می‌تونید جواب همه جمله هارو همون لحظه که بیان میشن، بدید:این اگه پاسخ های کوتاه بدید می‌تونه جواب بده. ولی اگه جواب هاتون بلندتر باشن، می‌تونه باعث بشه دوستتون به سختی داستانش رو تموم کنه. پس این استراتژی عالی نیست. ابطال کردن [Debounced]می‌تونید منتظر بمونید تا وقتی دیگه حرف نزنه. مثلاً، اگه یه مکث طولانی داشته باشه، می‌تونید جوابتون رو شروع کنید:اگه دوستتون گاهاً بین حرفاش مکث بکنه این استراتژی می‌تونه جواب بده. گرچه اگه یه چند دقیقه بدون وقفه حرف بزنه، کلاً نمی‌تونید جواب بدید:کنترل کردن [Throttled]می‌تونید با خودتون قرار بذارید که حداکثر هر یک دقیقه، یک جواب بدید. اینطوری، آماره اینکه الان چند ثانیه است صحبت نکردید رو دارید. همینکه شد یک دقیقه و هنوز صحبت نکرده بودید، جوابتون رو درست بعد از جمله ی بعدیه دوستتون می‌چپونید:این چه ربطی به ری‌اکت داره؟&quot;جملات&quot; دوستتون event هایی مثل کلیکِ یه دکمه یا تایپ کردن با کیبورد هستن. &quot;جواب ها&quot; ی شما آپدیت های صفحه ان.از ابطال کردن [debouncing] یا کنترل کردن [throttling] وقتی استفاده می‌کنید که کاربر داره یه کاری رو خیلی تند تند انجام میده (مثل تایپ کردن)، و آپدیت کردن صفحه در جواب هر رویداد جداگانه زیادی کُنده. پس یا منتظر میشید که کاربر تایپ کردنش رو تموم کنه (ابطال کردن) یا هر از چندگاهی صفحه رو آپدیت می‌کنید، مثلاً هر یک ثانیه یه بار (کنترل کردن).توی ری‌اکت ۱۸ چطور؟قسمت جالب قضیه اینجاست که startTransition در موارد زیادی باعث بیهوده شدن هر دو استراتژی میشه. بیایید یه استراتژی دیگه هم که قبل از ری‌اکت ۱۸ نداشتید اضافه کنیم:تعاونی [Cooperative]شما به محض اینکه دوستتون یه جمله میگه جوابش رو میدید، بی هیچ محلتی. اما با دوستتون توافق کردید که می‌تونه هر وقت خواست بپره وسطه حرفتون اگه می‌خواست حرفشو ادامه بده. پس در این حالت شما جوابتون رو نصفه رها می‌کنید. بعد بلافصله بعد از جمله بعدی، دوباره تلاش می‌کنید. و به همین شکل:(البته اینم توافق می‌کنید که اگه مقدار معینی زمان گذشت و شما جوابی نداده بودید شما هم توی حرف اون می‌پرید. این باعث میشه از اون حالتی که شما برای یه مدت طولانی هیچ حرفی نمی‌زدید جلوگیری بشه.)توجه کنید که توی این استراتژی شما هیچ زمانی رو هدر نمی‌دید و همچنین از ادامه دادن دوستتون هم جلوگیری نمی‌کنید.این بین سه تا راه کار قبلی بهترینه. (کی فکرشو می‌کرد که تعاونی بودن [being cooperative] کمک می‌کنه!)اگه بخوایم با کُد مثال بزنیم، این بدین معناست که ری‌اکت بلافاصله بعد از اینکه کاربر شروع می‌کنه به تایپ کردن، شروع می‌کنه به render کردن. هیچ نیازی نیست اول یکم صبر کنه بعد (مثل کاری که تو ابطال کردن [debouncing] می‌کنه). اگه کاربر دوباره تایپ کرد، ری‌اکت صرفا اون کارشو رها می‌کنه و دوباره از اول شروع می‌کنه. اگه render کردن به اندازه ای که توقف لای event ها جا بده سریع بود، اون موقع هیچ زمانی رو هدر ندادید (با بیهوده صبر کردن). همچنین هیچ زمانی رو واسه تموم کردن render ای که دیگه بهش نیازی نیست هدر ندادید.میتونید یه دمو از تفاوت های اینا اینجا ببینید. یه چیزی توی input بنویسید. هر چی بیشتر بنویسید، نمودار پیچیده‌تری هم کشیده میشه (که مجازاً کُند شده تا نکته رو نشون بده). رفتار های متفاوتِ بین ۳ تا استراتژی رو مشاهده کنید. وقتی یه متن طولانی رو پشت هم توی input تایپ می‌کنید چه رفتاری نشون میده؟کدوم یکی حس هموارتری داره؟اساس زیرْ درختی [SUB-TREE BASIS]نویسنده: gaearonبنظرم این به یک جمله ی توی ۴# ارجاع داره.این ویژگی ها به صورت مشارکت اختیاری توی یک اساس زیرْ درختی [sub-tree basis] بدون فعال کردن حالت strict برای کل اپلیکیشن‌تون هستن.جمله بندی گیج کننده ای داره {خدایی..}. اینجا &quot;توی یک اساس زیرْ درختی&quot; به معنای &quot;برای تک به تک اعضای درخت بجای کل app&quot; هست. من اگه بودم اینو اینطوری می‌گفتم:می‌تونید شروع کنید به استفاده از ویژگی ها روی قسمت کوچکی از درختتون بدون اینکه لازم باشه حالت strict رو برای کل اپلیکیشن‌تون فعال کنید.تحولِ اِسْتِیت [STATE TRANSITION] نویسنده: gaearonبه زبان محاوره، یه &quot;تحولِ state&quot; معادله با &quot;تغییر state&quot;. مثلاً، شاید شما state عه activeTab رو از &quot;خانه&quot; به &quot;پروفایل&quot; تغییر بدید. می‌تونید بگید این یه &quot;تحولِ state&quot; عه از خانه به پروفایل.معمولاً ملت منظورشون از &quot;تحول&quot; [transition] آپدیت های بزرگتریه. مثل وقتایی که اتفاق های بیشتری میوفته. شاید یه سری داده باید fetch بشن، یه قسمت بزرگی از صفحه دچار تغییر و تحول بشه، شاید یه مقدار انیمیشن باشه.ری‌اکت ۱۸ بر اساس این بینش ساخته شده یه مفهومی صریح از &quot;تحولات&quot; [transitions] رو معرفی می‌کنه (۴۱#). با علامت گذاری یه آپدیت state بعنوان یک تحول [transition]، به ری‌اکت این اشاره می‌کنید که این ممکنه یه مقدار کار ببره. ری‌اکت اجازه میده که تحولات [transitions] توسط آپدیت های ضروری تر قطع بشن، مثل تایپ کردن توی یه input. در آینده، ما داریم ادغام کردن این مفهوم رو با انیمیشن ها هم در نظر می‌گیریم.کامپوننت های سرور [SERVER COMPONENTS] نویسنده: gaearonکامپوننت های سرور یه ویژگیِ آزمایشیِ ری‌اکتیِ جدید هستند. احتمال داره که جزئی از ری‌اکت ۱۸ نباشن، ولی بالاخره یه زمانی به ری‌اکت اضافه خواهند شد بعداً. به شدت پیشنهاد می‌کنیم صحبت معرفیش رو مشاهده کنید که ایده اش رو توضیح میده چون هیچ چیزی تاحالا واقعاْ شبیهش نبوده، پس مقایسه کردنش به چیزهایی که وجود دارن یکم سخته.می‌تونید اینطوری بهش فکر کنید. یه سرور (جایی که ممکنه مرکز داده [databse] تون باشه) و یه client (مثلاً یه گوشی یا یه کامپیوتر) دارید. مرورگر روی client اجرا میشه. اپلیکیشن ری‌اکتی تون هم روی client اجرا میشه. پس کامپوننت های شما:&lt;Panel&gt;
    &lt;SearchField /&gt;
    &lt;FriendList /&gt;
&lt;/Panel&gt;هم روی client اجرا میشن. (روی گوشی و یا کامپیوترِ یه کاربر).این به این معناست که:تا قبل از اینکه تگِ جاوا اسکریپتیِ &lt;/ script&gt; به طور کامل load نشده باشه، کار نمیکنن.اگه لازم باشه یه مقدار داده از سرور بگیرن (مثلاً لیست دوستان!)، باید کد مخصوصش رو بنویسید.کامپوننت های سرور بهتون این اجازه رو میدن که کامپوننت هاتون رو روی سرور قرار بدید. مثلاً، اگه کامپوننت های &lt;Panel&gt; و &lt;FriendList&gt; به خودیِ خود هیچ event handler (مثل کلیک) یا state ای ندارند، دیگه دلیلی نداره که حتماً روی کامپیوتر کاربر اجرا بشن. می‌تونن روی سرور اجرا بشن، درست همونطوری که API شما روی سرور اجرا میشه!چرا اینطوری بهتره؟اینطوری تنها کامپوننتی که توی تگ &lt;/ script&gt; وجود داره SearchField عه. دیگه نیازی به دانلود کردن کد Panel یا FriendList نیست. اینطوری دیگه FriendList نیازی به کد مخصوصی واسه &quot;fetch&quot; کردن داده ها از روی سرور نداره. می‌تونه به طور مستقیم داده هارو بخونه چون همینطوریش روی سروره.پس سرور کامپوننت ها راهی هستن برای:نگه داشتن یه سری از کامپوننت های ری‌اکتی روی سرور که دیگه کدشون روی به کامپیوتر کسی نفرستید (این باعث کوچکتر شدن bundle تون و سریعترین شدن اپلیکیشنتون میشه!)ساده کردن fetch کردن داده (به جای این که یه کامپوننت داده های مورد نیازش رو توی effect ها &quot;fetch&quot; کنه، می‌تونه مستقیماً اونارو از روی سرور بخونه چون که روی سرور تشریف داره)فکر کردن به سرور و client به عنوان یک درخت واحد بجای دو تا بخش مختلف که مجبورن با هم &quot;حرف بزنن&quot;.هوک ها و هوک های سفارشی [HOOKS AND CUSTOM HOOKS]نویسنده: shaundaiراه های مختلفی برای نوشتن کامپوننت وجود داره، ولی کامپوننت های تابعی [functional components] عالین چون بهتون اجازه میدن به راحتی محاسبات پیچیده انجام بدید و منطق رو به آسونی به اینور اونور منتقل کنید. مثلاً اگه می‌خواید یه فایل json. طولانی به همراه داده رو بگیرید و بعد اون داده رو به عنوان یه جدول روی وب‌سایت یه نفر render کنید، می‌تونید همهٔ این کارا رو اساساً با یک تابع انجام بدید. کامپوننت های تابعی بی‌نقصن، فقط یه &quot;مچتو گرفتم&quot; دارن: نمی‌تونن state رو نگه دارن.قبلنا (قبل از هوک ها) اگه می‌خواستید از state استفاده کنید، باید از چند نوع کامپوننت مختلف استفاده می‌کردید (از کامپوننت های کلاسی [class components] برای هر چیزی که state داره و از کامپوننت های تابعی [functional components] برای اینکه با اطلاعات یه حرکتی بزنید) و این خیلی کمتر تمیز بود.هوک ها وارد شدن. هوک ها بهتون اجازه میدن ویژگی های ری‌اکتی ای مثل state و متد های lifecycle رو &quot;قلاب کنید&quot; {معنی لغوی هوک میشه قلاب یا قلاب کردن} تا که کد تمیز و شفافی داشته باشید. بعضی هوک ها &quot;به طور پیش فرض&quot; وجود دارن (برای دریافت و آپدیت کردن state، شما useState رو دارید، یا برای ممکنه برای تغییر دادن چیزها با استفاده از متد های lifecycle از useEffect استفاده کنید).نویسنده: gaearonبنظرم هم &quot;کامپوننت های تابع&quot; [function components] هم &quot;کامپوننت های تابعی&quot; [functional components] در زبان محاوره مشکلی ندارن. ما وقتی که hooks رو معرفی کردیم بجای &quot;functional&quot; که قبلاً استفاده ‌می‌شد گفتیم &quot;function&quot; چون نگران این بودیم که ممکنه ناب‌گرایانِ [purists] برنامه نویسیِ تابعی [functional programming] به اینکه هوک ها در اون معنای برنامه نویسی بر اساس تابع [functional programming]، &quot;تابعی نیستن&quot; [not being functional] خًرده بگیرند. (هرچند یه جورایی هستند — ولی خب اون یه بحث جداست.) من شخصاً ایرادِ بنی اسرائیلی ازشون نمی‌گیرم مگر توی داکیومنت ها [docs]. جایی که قراره فقط &quot;کامپوننت&quot; صداشون کنیم از اونجایی که کامپوننت های کلاسی [class components] کم کم دارن به عنوان یه مورد تخصصی شده، بیشتر میراثی، محو میشن.رِفرِش سریع [FAST REFRESH]نویسنده: meganesu توی ریپازیتوریه TIL ام یه نگاهی به این انداختم:رفرش سریع [fast refresh] یه ویژگیِ ری‌اکته که وقتی توی ادیتور (مثلاً VS Code) روی کُدتون تغییراتی اعمال می‌کنید بلافاصله کامپوننت هارو render می‌کنه. با رفرش سریع [fast refresh]، نمای مرورگرتون بدون از دست دادن state عه کامپوننت ها آپدیت میشه. که منجر به بهبود یافتن تجربه ی توسعه دهندگی میشه.رفرش سریع [fast refresh] تکرارِ جدیدیست بر hot reloading.  قرار بود hot reloading هم مزایای مشابهی داشته باشه، ولی نتونست به خوبی با کاموننت های تابعی [functional components]  و هوک ها کار کنه. همچنین error ها رو هم به خوبی handle نمی‌کرد، اینطوری که اگه یه اشتباه تایپی می‌کردید مجبور میشدید app تون رو کلاً restart کنید. رفرش سریع [fast refresh] اون کاستی هارو برطرف کرده.استیتِ اَپ، استیتِ کامپوننت، استیتِ رابط کاربری[APP STATE, COMPONENT STATE, UI STATE]نویسنده: gaearonکامپوننت های ری‌اکتیِ شما اطلاعات رو به رابط کاربری [UI] منتقل می‌کنند. دو نوع اطلاعات داریم.بعضی از این اطلاعات مادامِ حضور یک کاربر [user session] هیچ وقت تغییر نمی‌کنند. مثلاً چیدمان وب‌سایت شما، آیکون های روی دکمه هاتون، و ترتیب بخش ها روی صفحه.بقیه اطلاعات ممکنه در پاسخ به تعامل کاربر تغییر کنند. مثلاً، آیا یه دکمه hover شده یا نه. کاربر چند بار روی &quot;اضافه کردن&quot; کلیک کرده. محتوای سبد خریدشون یا پیامی که در حال تایپ کردنش بودن.اطلاعاتی که در نتیجهٔ تعامل کاربر تغییر می‌کنه رو بهش میگن &quot;state&quot;.هر اطلاعاتی یه طول عمری داره. به یه چیزی وصله. مثلاً، متغیر های جاوا اسکریپتیِ‌ عادی به function call ها وصلن. فقط مادامی زنده ان که شما درون تابع هستید. وقتی از یک تابع خارج میشید، &quot;موجودیت&quot; متغیر های اون call از بین میره. (بجز بحث closure ها، که وقتی توابع رو nest می‌کنین بوجود میان، و باعث میشن که یه تابع nest شده بتونه متغیر هایی از تابع خارجی ای که call شده رو &quot;همچنان مشاهده کنه&quot;.)توی ری‌اکت، هر دفعه که یه کامپوننت render میشه، یه function call جداگانه به حساب میاد. پس اگه سعی کنید مقداری اطلاعات مثل محتوای سبد خرید رو توی یه متغیر عادی ذخیره کنید، بعد از render بعدی به سادگی محو میشه. واسه اینه که ری‌اکت مفهومی مِن باب &quot;متغیر های اِستیت&quot; [state variables] داره که با useState تعریفش می‌کنید. اونا با قسمتی از درخت مرتبطن — مثلاً، یه text input عه مشخص یا یه سبد خریدی که روی صفحه می‌بینید — بجای اینکه با یه function call مرتبط باشن.اینکه کجا متغیر اِستِیتون رو میسازید حائز اهمیته. میشه اینطوری بهش فکر کرد. اگه چیزی رو توی دو قسمت از صفحه render کنید، دلتون می‌خواد هماهنگ [synchronized] باشن یا نه؟مثلاً، render کردن دو تا فیلدِ نظر [comment field] معنیش این نیست که می‌خواین وقتی توی یکی تایپ می‌کنید اون یکی هم آپدیت بشه. پس اینکه state رو بذاریم توی فیلدِ نظر منطقیه. اینطوری هر کپی مستقل میشه.ولی شاید دارید نظری که قبلاً ارسال شده رو توی دو جا render می‌کنید. اگه یکیش رو edit کنید، و ذخیره اش کنید، منطقیه که انتظار داشته باشیم هر دوشون edit شما رو منعکس کنن. پس اطلاعات لیستی از نظرات باید جایی خارج از کامپوننتون باشه. — شاید، توی parent مشترکشون یا توی یه جور cache.این چیزیه که ملت منظورشونِ وقتی راجع به انواع مختلف state حرف میزنن. اینا اصطلاحات تکنیکال نیستن، بلکه &quot;اِستیتِ رابط کاربری&quot; [UI state] اغلب به معنای یه جور state ایه که به طور خاص مربوطه به یه جور رابط کاربریِ بهم چسبیده [concrete UI widget]. مثل متنِ text input. درحالیکه &quot;اِستیتِ عه اپ&quot; [app state] معمولاً به معنای مقداری اطلاعاتِ به اشتراک گذشته شده در بین تعداد زیادی کامپوننته و لازمه که هماهنگ باشه [in sync]. پس معمولاً خارج از اونا گذاشته میشه.رِندِر ها: رِندِر ها، ری-رِندِر ها، رِندِر های بی فایده؟?RENDERS: RENDERS, RE-RENDERS, WASTEFUL RENDERSنویسنده: gaearonوقتی که کاربر کاری انجام میده (مثلا کلیک کردن روی یه دکمه)، شاید بخواین چیزی که روی صفحه هست رو تغییر بدین. که با set کردن state انجامش میدید. در پاسخ، ری‌اکت یه &quot;render&quot; انجام میده.در حین یک render، ری‌اکت اون کامپوننتی که شما state اش رو set کردین رو صدا می‌کنه. کامپوننت شما اون چیزی که باید روی صفحه باشه رو return میکنه. بعد، ری‌اکت همینکارو واسه کامپوننت های زیرینِ اون کامپوننته انجام میده (چون این احتمال که شاید اونا هم چیز متفاوتی نشون بدن وجود داره). این پروسه اسمش render کردنه.این شاید شمارو یادِ برنامه ریزیِ از بالا به پایین بندازه. یه شرکت طراحی ممکنه یه سفارش دریافت کنه. کارگردان طرح، چشم اندازی رو تنظیم می‌کنه و تصویرسازی [illustration]، تایپوگرافی، یا طراحی لوگو رو میده دست کسانی که تخصص اون کار رو دارن. اونا هم، به نوبت، یحتمل قسمت هایی از اون کار رو میدن دست بقیه همکار ها. و به همین ترتیب. در نهایت نتیجه ای مرکب از کار آدم های مختلف حاصل میشه.این معادل چگونگیه مرکب بودنِ اتفاقیه که نهایتاً روی صفحه میوفته از نتایج render کامپوننت های مختلف.فرض کنیم اون مشتریِ شرکت طراحی حالا می‌خواد یه چیزی رو تغییر بده. &quot;بیاید رنگ هارو بهتر کنیم.&quot; پس اون پروسهٔ از بالا به پایین مجدداً شروع میشه. کارگردان طرح با طراحی حرف میزنه که با کسی که طرح های اولیه رو میسازه حرف میزنه، که تغییرات رو اعمال می‌کنه. بعد یه طرح جدید گیرمون میاد.این میشه همون &quot;re-render&quot;. یعنی وقتی که state رو دوباره set می‌کنید، ری‌اکت کامپوننت هاتون رو صدا می‌کنه تا بفهمه چی باید روی صفحه باشه، و بعد صفحه رو آپدیت می‌کنه. &quot;re-render&quot; یعنی &quot;دوباره render کردن&quot;، نه هیچ چیزی فراتر از اون.نهایتاً، یه &quot;render عه تلف شده / بی فایده&quot; [wasted render] یعنی قسمتی از کاری که انجام شده بیهوده بود. مثلاً، اگه مشتریمون بگه &quot;یکم با فونت هاش بازی کنید&quot; و کل شرکت شروع کنه به تکرار کردن دوباره همه چیز. ولی واقعیتش اینه که فقط کارگردان طرح و طراح فونت لازم بود درگیر بشن. نیازی به درگیر کردن کسی که روی پالت رنگ ها کار می‌کرد نبود.توی ری‌اکت، این ممکنه وقتی که دارید state عه کامپوننتی که شامل کامپوننت های خیلی زیادی میشه رو آپدیت می‌کنید اتفاق بیوفته. ممکنه که آپدیت روشون تأثیری نذاره، اما بازم ری‌اکت باید از تک تکشون بپرسه که آیا می‌خوان چیز متفاوتی رو نشون بدن یا نه. پس اگه در پاسخ چیزی رو عوض نکن این یه &quot;کار بیهوده&quot; است.چندین راه متداول برای بهینه سازیِ render های &quot;تلف شده / بیهوده&quot; وجود داره:می‌تونید state رو اگه روی یه سری کامپوننت تأثیری نمیذاره، توی درخت عمیق تر کنید. اینطوری دیگه ری‌اکت از اونا چیزی نمی‌پرسه.می‌تونید چندتا کامپوننت رو از بالا به عنوان بچه هایی از اون کامپوننت که state اش آپدیت شده پاس بدید. اینطوری ری‌اکت میدونه که اون کامپوننت هایی که از &quot;بالا&quot; اومدن به این آپدیتِ state اهمیتی نمیدن، و نیازی به تغییر ندارن.می‌تونید بعضی از کامپوننت هارو به عنوان &quot;memoized&quot; علامت بزنید که به این معناست که اونا آخرین prop و آخرین نتیجه render شون رو &quot;به خاطر میسپارن&quot;. اینطوری، قبل از re-render، ری‌اکت بررسی می‌کنه ببینه آیا props شون تغییری کرده یا نه. اگه نکرده، در حالی که داره render می‌کنه از اونا رد میشه.پی‌نوشت: می‌دونم که یحتمل شرکت های طرحی اینریختی از بالا به پایین کار نمی‌کنن. فقط یه استعاره بود.</description>
                <category>جلال حامد</category>
                <author>جلال حامد</author>
                <pubDate>Wed, 15 Sep 2021 10:24:07 +0430</pubDate>
            </item>
                    <item>
                <title>جاوا اسکریپت لازم برای ری‌اکت</title>
                <link>https://virgool.io/@iamjalalhamed/%D8%AC%D8%A7%D9%88%D8%A7-%D8%A7%D8%B3%DA%A9%D8%B1%DB%8C%D9%BE%D8%AA-%D9%84%D8%A7%D8%B2%D9%85-%D8%A8%D8%B1%D8%A7%DB%8C-%D8%B1%DB%8C-%D8%A7%DA%A9%D8%AA-jks0suonosic</link>
                <description>عکاس بنجامین وروسمتن اصلی مقاله: JavaScript To Know for React نوشته Kent C. Doddsویژگی های مورد نیاز جاوا اسکریپتی که برای آموختن و استفاده کردن از ری‌اکت باید بدانید.یکی از چیزهایی که راجع به ری‌اکت نسبت به بقیه فریم‌ورک هایی که ازشون استفاده کردم خیلی دوستش دارم اینه که چقدر ناچاریم به جاوا اسکریپت پناه ببریم وقتی که از ری‌اکت استفاده می‌کنیم. هیچ الگو DSL ای وجود نداره (JSX به جاوا اسکریپت محسوس کامپایل میشه)، API کامپوننت ها با اضافه شدن ری‌اکت هوکس فقط ساده تر شده، و فریم‌ورکش انتزاع خیلی کوچکی خارج از مسئله های اصلی UI ای که قراره حلشون کنه رو بهتون میده.واسه همین، آموختن ویژگی های جاوا اسکریپت براتون خیلی مطلوبه تا بتونید در ساختن برنامه های کاربردی با ری‌اکت مؤثر باشید. پس این شما و اینم یه مقدار ویژگی جاوا اسکریپتی که بهتون پیشنهاد می‌کنم یه مقدار زمان بذارید و یاد بگیرید. باشد که در استفاده از ری‌اکت تا جای ممکن مؤثر واقع بشید.قبل از اینکه وارد یه سری قضایای سینتکسی بشیم، یه چیز دیگه ای که خیلی می‌تونه در فهم ری‌اکت مفید واقع بشه مفهوم کلوژر [closure] هست. یه مقاله عالی در باب این مفهوم اینجاست: mdn.io/closure.خیله خب، بریم سراغ ویژگی های JS ای که در مواجهه با ری‌اکت می‌خواید بدونید.الگو های تحت اللفظی [Template Literals]الگو های تحت اللفظی شبیه string های ساده‌ان با قدرت های ماورائی:const greeting = &#039;Hello&#039;
const subject = &#039;World&#039;
console.log(`${greeting} ${subject}!`) // Hello World!

// :معادله با
console.log(greeting + &#039; &#039; + subject + &#039;!&#039;)

// :توی ری‌اکت
function Box({className, ...props}) {
  return &lt;div className={`box ${className}`} {...props} /&gt;
} MDN: Template Literalsمختصر نویسی اسامی دارایی [Shorthand property names]این انقدر متداول و کارآمده که دیگه الان بدون اینکه بهش فکر کنم انجامش میدم.const a = &#039;hello&#039;
const b = 42
const c = {d: [true, false]}
console.log({a, b, c})

// :معادله با
console.log({a: a, b: b, c: c})

// :توی ری‌اکت
function Counter({initialCount, step}) {
  const [count, setCount] = useCounter({initialCount, step})
  return &lt;button ={setCount}&gt;{count}&lt;/button&gt;
}MDN: Object initializer New notations in ECMAScript 2015توابع پیکانی [Arrow functions]توابع پیکانی یه راه دیگه برای نوشتن توابع در جاوا اسکریپت هستن، ولی یه چندتا تفاوت معنایی هم دارن. خوشبختانه ما در دنیای ری‌اکت، نیازی نیست که اونقدری نگران this باشیم اگه از ری‌اکت هوکس توی پروژه مون استفاده کنیم (بجای کلاس ها)، ولی توابع پیکانی اجازه نوشتن توابع ناشناس مختصر و return های ضمنی رو میدن، در نتیجه شما به کرات توابع پیکانی رو می‌بینید و می‌خواید که ازشون استفاده کنید.const getFive = () =&gt; 5
const addFive = a =&gt; a + 5
const divide = (a, b) =&gt; a / b

// :معادله با
function getFive() {
  return 5
}
function addFive(a) {
  return a + 5
}
function divide(a, b) {
  return a / b
}
// :توی ری‌اکت
function TeddyBearList({teddyBears}) {
  return (
    &lt;ul&gt;
      {teddyBears.map(teddyBear =&gt; (
        &lt;li key={teddyBear.id}&gt;
          &lt;span&gt;{teddyBear.name}&lt;/span&gt;
        &lt;/li&gt;
      ))}
    &lt;/ul&gt;
  )
}یه چیزی که راجع به مثال بالا بهتره بهش دقت کنیم پرانتز های باز و بسته هستن (. این یه روش مرسوم برای استفاده حداکثری از قابلیت return ضمنی توابع پیکانیه وقتی که داریم با JSX کار می‌کنیم. MDN: Arrow Functionsتخریب کردن [Destructuring]تخریب کردن احتمالا ویژگی جاوا اسکریپتی مورد علاقه منه. من همش اشیاء [obejcts] و آرایه ها [arrays] رو تخریب می‌کنم (و اگه شما هم از useState استفاده می‌کنین پس یحتمل شما هم همینکارو می‌کنین، به این شکل). عاشق این همه اعلامی بودنشم.// const obj = {x: 3.6, y: 7.8}
// makeCalculation(obj)

function makeCalculation({x, y: d, z = 4}) {
  return Math.floor((x + d + z) / 3)
}

// :معادله با
function makeCalculation(obj) {
  const {x, y: d, z = 4} = obj
  return Math.floor((x + d + z) / 3)
}

// :که معادله با
function makeCalculation(obj) {
  const x = obj.x
  const d = obj.y
  const z = obj.z === undefined ? 4 : obj.z
  return Math.floor((x + d + z) / 3)
}

// :توی ری‌اکت
function UserGitHubImg({username = &#039;ghost&#039;, ...props}) {
  return &lt;img src={`https://github.com/${username}.png`} {...props} /&gt;
}MDN: Destructuring assignmentحتما مقاله MDN رو بخونید. مطمئنا یه چیز جدید یاد می‌گیرید. وقتی تموم شد، سعی کنید کد پایین رو طوری refactor کنید که توی یک خط از قابلیت تخریب کنندگی استفاده کنه:function nestedArrayAndObject() {
  // کنید که از قابلیت تخریب کنندگی استفاده کنه refactor این کد رو طوری
  const info = {
    title: &#039;Once Upon a Time&#039;,
    protagonist: {
      name: &#039;Emma Swan&#039;,
      enemies: [
        {name: &#039;Regina Mills&#039;, title: &#039;Evil Queen&#039;},
        {name: &#039;Cora Mills&#039;, title: &#039;Queen of Hearts&#039;},
        {name: &#039;Peter Pan&#039;, title: `The boy who wouldn&#039;t grow up`},
        {name: &#039;Zelena&#039;, title: &#039;The Wicked Witch&#039;},
      ],
    },
  }
  // const {} = info // &lt;-- بعدی رو با این جایگزین کنید &#039;const&#039; چند خط
  const title = info.title
  const protagonistName = info.protagonist.name
  const enemy = info.protagonist.enemies[3]
  const enemyTitle = enemy.title
  const enemyName = enemy.name
  return `${enemyName} (${enemyTitle}) is an enemy to ${protagonistName} in &amp;quot${title}&amp;quot`
}پیش‌فرض پارامترها [Parameter defaults]اینم یه ویژگی دیگه که من همش ازش استفاده می‌کنم. راهی به قطع قدرتمند برای بیان مقادیر پیش‌فرض به شیوه اعلامی برای توابع شما.// add(1)
// add(1, 2)
function add(a, b = 0) {
  return a + b
}

// :معادله با
const add = (a, b = 0) =&gt; a + b

// :معادله با
function add(a, b) {
  b = b === undefined ? 0 : b
  return a + b
}

// :توی ری‌اکت
function useLocalStorageState({
  key,
  initialValue,
  serialize = v =&gt; v,
  deserialize = v =&gt; v,
}) {
  const [state, setState] = React.useState(
    () =&gt; deserialize(window.localStorage.getItem(key)) || initialValue,
  )

  const serializedState = serialize(state)
  React.useEffect(() =&gt; {
    window.localStorage.setItem(key, serializedState)
  }, [key, serializedState])

  return [state, setState]
}MDN: Default parametersباقی/پخش [Rest/Spread]سینتکس ... (سه نقطه) رو میشه به عنوان یه جور سینتکس &quot;مجموعه&quot; بهش فکر کرد از اونجایی که روی مجموعه ای از مقادیر، عملیاتی رو انجام میده. من همیشه ازش استفاده میکنم و قویاً پیشنهاد می‌کنم شما هم یاد بگیرید که کجا و چگونه میشه به خوبی ازش استفاده کرد. در حقیقت در زمینه های مختلف، معانی مختلفی میگیره، پس فراگرفتن تفاوت های ظریف، اونجاها بهتون کمک می‌کنه.const arr = [5, 6, 8, 4, 9]
Math.max(...arr)
// :معادله با
Math.max.apply(null, arr)

const obj1 = {
  a: &#039;a from obj1&#039;,
  b: &#039;b from obj1&#039;,
  c: &#039;c from obj1&#039;,
  d: {
    e: &#039;e from obj1&#039;,
    f: &#039;f from obj1&#039;,
  },
}
const obj2 = {
  b: &#039;b from obj2&#039;,
  c: &#039;c from obj2&#039;,
  d: {
    g: &#039;g from obj2&#039;,
    h: &#039;g from obj2&#039;,
  },
}
console.log({...obj1, ...obj2})
// :معادله با
console.log(Object.assign({}, obj1, obj2))

function add(first, ...rest) {
  return rest.reduce((sum, next) =&gt; sum + next, first)
}
// :معادله با
function add() {
  const first = arguments[0]
  const rest = Array.from(arguments).slice(1)
  return rest.reduce((sum, next) =&gt; sum + next, first)
}

// :توی ‌ری‌اکت
function Box({className, ...restOfTheProps}) {
  const defaultProps = {
    className: `box ${className}`,
    children: &#039;Empty box&#039;,
  }
  return &lt;div {...defaultProps} {...restOfTheProps} /&gt;
}MDN: Spread syntaxMDN: Rest parametersماژول های اِکما اسکریپت [ESModules]اگه در حال ساختن یه app با ابزار های مدرن هستین، شانس اینکه از ماژول ها پشتیبانی کنه بالاس، اینکه یاد بگیرید سینکتسش هم چجوری کار می‌کنه ایده ی خوبیه چون هر اپلیکیشنی حتی در سایز های جزئی هم یحتمل نیاز داشته باشه که از ماژول ها برای استفاده مجدد از کد و سازمان دهی استفاده کنه.export default function add(a, b) {
  return a + b
}

/*
 * import add from &#039;./add&#039;
 * console.assert(add(3, 2) === 5)
 */

export const foo = &#039;bar&#039;

/*
 * import {foo} from &#039;./foo&#039;
 * console.assert(foo === &#039;bar&#039;)
 */

export function subtract(a, b) {
  return a - b
}

export const now = new Date()

/*
 * import {subtract, now} from &#039;./stuff&#039;
 * console.assert(subtract(4, 2) === 2)
 * console.assert(now instanceof Date)
 */

// ایمپورت های داینامیک
import(&#039;./some-module&#039;).then(
  allModuleExports =&gt; {
    // همون آبجکتی خواهد بود که می‌گیرید اگه از allModuleExports آبجکت
    // .استفاده کرده باشید import * as allModuleExports from &#039;./some-module&#039;
    // تنها فرقش اینه که به صورت غیرهم‌زمان بارگذاری خواهد شد که این می‌تونه
    // .توی بعضی موارد مفید باشه
  },
  error =&gt; {
    // رسیدگی به خطا
    // این زمانی اتفاق میوفته که یه خطایی در حین بارگذاری یا اجرا کردن ماژول داشته باشیم
  },
)

// :توی ری‌اکت
import React, {Suspense, Fragment} from &#039;react&#039;

// React ایمپورت داینامیک یه کامپوننت
const BigComponent = React.lazy(() =&gt; import(&#039;./big-component&#039;))
// big-component.js would need to &amp;quotexport default BigComponent&amp;quot for this to workMDN: importMDN: exportبه عنوان یه مرجع دیگه، من (جناب Kent C. Dodds) یه ارائه کامل راجع به این سینتکس دادم و شما می‌تونید اون ارائه رو اینجا نگاه کنید.سه تایی ها [Ternaries]من عاشق سه تایی هام. اونا به شکل زیبایی اعلامی ان. بخصوص توی JSX.const message = bottle.fullOfSoda
  ? &#039;The bottle has soda!&#039;
  : &#039;The bottle may not have soda :-(&#039;

// معادله با
let message
if (bottle.fullOfSoda) {
  message = &#039;The bottle has soda!&#039;
} else {
  message = &#039;The bottle may not have soda :-(&#039;
}

// :توی ری‌اکت
function TeddyBearList({teddyBears}) {
  return (
    &lt;React.Fragment&gt;
      {teddyBears.length ? (
        &lt;ul&gt;
          {teddyBears.map(teddyBear =&gt; (
            &lt;li key={teddyBear.id}&gt;
              &lt;span&gt;{teddyBear.name}&lt;/span&gt;
            &lt;/li&gt;
          ))}
        &lt;/ul&gt;
      ) : (
        &lt;div&gt;There are no teddy bears. The sadness.&lt;/div&gt;
      )}
    &lt;/React.Fragment&gt;
  )
}متوجه هستم که سه تایی ها می‌تونن یجور عکس‌العمل غیر ارادی حاکی از انزجار از سمت بعضیا دریافت کنن. کسایی که مجبور بودن تلاش برای پیدا کردن یه درکی از سه تایی ها رو تحمل کنن تا قبل از اینکه prettier سر و کله‌ش پیدا بشه و کدمون رو تر و تمیز کنه. اگه هنوز از prettier استفاده نکردین، قویاً بهتون توصیه می‌کنم از همین الان شروع کنین. Prettier یه کاری میکنه سه تایی هاتون بسیار راحت تر خونده بشن.MDN: Conditional (ternary) operatorمتد های آرایه [Array Methods]آرایه ها محشرن و من همیشه خدا از متد های آرایه استفاده می‌کنم! یحتمل غالباً از متد های ذیل استفاده می‌کنم:findsomeeveryincludesmapfilterreduceاینم یه چندتا مثال:const dogs = [
  {
    id: &#039;dog-1&#039;,
    name: &#039;Poodle&#039;,
    temperament: [
      &#039;Intelligent&#039;,
      &#039;Active&#039;,
      &#039;Alert&#039;,
      &#039;Faithful&#039;,
      &#039;Trainable&#039;,
      &#039;Instinctual&#039;,
    ],
  },
  {
    id: &#039;dog-2&#039;,
    name: &#039;Bernese Mountain Dog&#039;,
    temperament: [&#039;Affectionate&#039;, &#039;Intelligent&#039;, &#039;Loyal&#039;, &#039;Faithful&#039;],
  },
  {
    id: &#039;dog-3&#039;,
    name: &#039;Labrador Retriever&#039;,
    temperament: [
      &#039;Intelligent&#039;,
      &#039;Even Tempered&#039;,
      &#039;Kind&#039;,
      &#039;Agile&#039;,
      &#039;Outgoing&#039;,
      &#039;Trusting&#039;,
      &#039;Gentle&#039;,
    ],
  },
]

dogs.find(dog =&gt; dog.name === &#039;Bernese Mountain Dog&#039;)
// {id: &#039;dog-2&#039;, name: &#039;Bernese Mountain Dog&#039;, ...etc}

dogs.some(dog =&gt; dog.temperament.includes(&#039;Aggressive&#039;))
// false

dogs.some(dog =&gt; dog.temperament.includes(&#039;Trusting&#039;))
// true

dogs.every(dog =&gt; dog.temperament.includes(&#039;Trusting&#039;))
// false

dogs.every(dog =&gt; dog.temperament.includes(&#039;Intelligent&#039;))
// true

dogs.map(dog =&gt; dog.name)
// [&#039;Poodle&#039;, &#039;Bernese Mountain Dog&#039;, &#039;Labrador Retriever&#039;]

dogs.filter(dog =&gt; dog.temperament.includes(&#039;Faithful&#039;))
// [{id: &#039;dog-1&#039;, ..etc}, {id: &#039;dog-2&#039;, ...etc}]

dogs.reduce((allTemperaments, dog) =&gt; {
  return [...allTemperaments, ...dog.temperament]
}, [])
// [ &#039;Intelligent&#039;, &#039;Active&#039;, &#039;Alert&#039;, ...etc ]

// :توی ری‌اکت
function RepositoryList({repositories, owner}) {
  return (
    &lt;ul&gt;
      {repositories
        .filter(repo =&gt; repo.owner === owner)
        .map(repo =&gt; (
          &lt;li key={repo.id}&gt;{repo.name}&lt;/li&gt;
        ))}
    &lt;/ul&gt;
  )
}MDN: Arrayاُپراتور ادغام شدن باطل [Nullish coalescing operator]اگه یه مقداری null یا undefined باشه، اون وقته که یحتمل بخواین به یه مقدار پیش‌فرض دلتون رو گرم کنین:// console.log(&amp;quot&amp;quot)
// :این اون کاریه که قبلاً غالباً انجام می‌دادیم
x = x || &#039;some default&#039;

// مقادیر معتبری بودن مشکل ساز بود &amp;quotfalse&amp;quot اما این وقتایی که توی اعداد یا بولیَن ها &amp;quot0&amp;quot یا

// :پس اگه می‌خواستیم یه همچین چیزی رو ساپورت کنیم
add(null, 3)

// :این کاری بود که باید قبلش انجام می‌دادیم
function add(a, b) {
  a = a == null ? 0 : a
  b = b == null ? 0 : b
  return a + b
}

// این کاریه که الان می‌تونیم انجام بدیم
function add(a, b) {
  a = a ?? 0
  b = b ?? 0
  return a + b
}

// :توی ری‌اکت
function DisplayContactName({contact}) {
  return &lt;div&gt;{contact.name ?? &#039;Unknown&#039;}&lt;/div&gt;}MDN: Nullish coalescing operatorزنجیر کردن اختیاری [Optional chaning]موسوم به &quot;اُپراتور اِلویس&quot;، به شما این اجازه رو میده که بی خطر به پراپرتی ها دسترسی پیدا کنین و توابعی رو call کنین ممکنه وجود داشته و یا نداشته باشن. قبل از زنجیر کردن اختیاری، از یه راه حل هک طور استفاده می‌کردیم که به falsy و truthy بودن وابسته بود.// console.log(&amp;quot&amp;quot)
// :کاری که قبل از زنجیر کردن اختیاری می‌کردیم
const streetName = user &amp;&amp; user.address &amp;&amp; user.address.street.name

// :کاری که الان می‌تونیم بکنیم
const streetName = user?.address?.street?.name

// باشه بازم اجرا میشه (که در اون undefined هم options این حتی اگه
// (میشه undefined هم onSuccess حالت
// میشد fail هیچ‌وقت تعریف نمی‌شد بازم options هرچند اگه
// .از اونجایی که زنجیر کردن اختیاری نمی‌تونه توی یه شیء ریشه ای که وجود نداره استفاده بشه
// if (typeof options == &amp;quotundefined&amp;quot) زنجیر کردن اختیاری بررسی هارو جایگزین نمی‌کنه. مثلا
const onSuccess = options?.onSuccess

// باشه هم بازم بدون هیچ خطایی اجرا میشه undefined حتی onSuccess این اگه
// (که در اون حالت، هیچ تابعی کال نمیشه)
onSuccess?.({data: &#039;yay&#039;})

// :و می‌تونیم همه ی اونارو ترکیب کنیم توی یه خط
options?.onSuccess?.({data: &#039;yay&#039;})

// وجود داشته باشه options یه تابعه اگه که onSuccess و اگه ۱۰۰٪ مطمئنید که
// پس دیگه به اون ؟. اضافه نیازی ندارید قبل از اینکه کالش کنید. از ؟. فقط در شرایطی استفاده کنید که
// .اون چیزی که سمت چپه محتمله که وجود نداشته باشه
options?.onSuccess({data: &#039;yay&#039;})

// in React:
function UserProfile&#40;{user}&#41; {
  return (
    &lt;div&gt;
      &lt;h1&gt;{user.name}&lt;/h1&gt;
      &lt;strong&gt;{user.bio?.slice(0, 50)}...&lt;/strong&gt;
    &lt;/div&gt;
  )
}فقط حواستون باشه که اگه دیدید که دارید خیلی توی کدتون از ؟. استفاده می‌کنید، شاید بخواید یه نگاهی به اونجایی که این مقادیر از اونجا سرچشمه میگیرن بندازید و مطمئن بشید که دائماً همون مقادیری رو بر می‌گردونن که باید.MDN: Optional chainingوعده‌ ها و همزمان/انتظار [Promises and async/await]این یکی یه موضوع گسترده اس و ممکنه لازم باشه یه مقدار باهاش تمرین کنید و خلاصه یکم زمان ببره تا لِمِش دستتون بیاد. وعده ها [promises] جای جایِ اِکوسیستمِ جاوا اسکریپت هستن و با تشکر از میزان زیادِ تثبیت شدگی ری‌اکت در همین اکوسیستم، جای جایِ ری‌اکت هم قرار دارن. (در حقیقت، خوده ری‌اکت توی کد بیسش از وعده ها [promises] استفاده می‌کنه).وعده ها [promises] بهتون توی مدیریت کردن کد غیرهمزمان [asynchronous] کمک می‌کنه و توسط خیلی از API های DOM هم return میشه همچنین از خیلی از کتابخونه های شخص ثالث هم همینطور. سینتکس همزمان/انتظار [async/await] یه سینتکس خاص واسه برخورد کردن با وعده هاست [promises]. این دو تا اصولاً دست در دست همن و با هم به کار میان.function promises() {
  const successfulPromise = timeout(100).then(result =&gt; `success: ${result}`)

  const failingPromise = timeout(200, true).then(null, error =&gt;
    Promise.reject(`failure: ${error}`),
  )
  const recoveredPromise = timeout(300, true).then(null, error =&gt;
    Promise.resolve(`failed and recovered: ${error}`),
  )

  successfulPromise.then(log, logError)
  failingPromise.then(log, logError)
  recoveredPromise.then(log, logError)
}

function asyncAwaits() {
  async function successfulAsyncAwait() {
    const result = await timeout(100)
    return `success: ${result}`
  }

  async function failedAsyncAwait() {
    const result = await timeout(200, true)
    return `failed: ${result}` // این اجرا نخواهد شد
  }

  async function recoveredAsyncAwait() {
    let result
    try {
      result = await timeout(300, true)
      return `failed: ${result}` // این اجرا نخواهد شد
    } catch (error) {
      return `failed and recovered: ${error}`
    }
  }

  successfulAsyncAwait().then(log, logError)
  failedAsyncAwait().then(log, logError)
  recoveredAsyncAwait().then(log, logError)
}

function log(...args) {
  console.log(...args)
}

function logError(...args) {
  console.error(...args)
}

// (? این مادرِ همه غیرهمزمانی هاست (خدایی خودش اینطوری نوشته
function timeout(duration = 0, shouldReject = false) {
  return new Promise((resolve, reject) =&gt; {
    setTimeout&#40;(&#41; =&gt; {
      if (shouldReject) {
        reject(`rejected after ${duration}ms`)
      } else {
        resolve(`resolved after ${duration}ms`)
      }
    }, duration)
  })
}

// :توی ری‌اکت
function GetGreetingForSubject({subject}) {
  const [isLoading, setIsLoading] = React.useState(false)
  const [error, setError] = React.useState(null)
  const [greeting, setGreeting] = React.useState(null)

  React.useEffect(() =&gt; {
    async function fetchGreeting() {
      try {
        const response = await window.fetch(&#039;https://example.com/api/greeting&#039;)
        const data = await response.json()
        setGreeting(data.greeting)
      } catch (error) {
        setError(error)
      } finally {
        setIsLoading(false)
      }
    }
    setIsLoading(true)
    fetchGreeting()
  }, [])

  return isLoading ? (
    &#039;loading...&#039;
  ) : error ? (
    &#039;ERROR!&#039;
  ) : greeting ? (
    &lt;div&gt;
      {greeting} {subject}
    &lt;/div&gt;
  ) : null
}MDN: PromiseMDN: async functionMDN: awaitنتیجه [Conclusion]بی تردید تعداد زیادی ویژگی برنامه نویسی وجود داره وقتی که داریم یه اپ ری‌اکتی می‌سازیم به کارمون میان، ولی اینا یه تعدادی از مورد علاقه های من بودن که می‌دیدم خودم گاه و بی گاه استفاده می‌کنم. امیدوارم براتون مفید بوده باشه.اگه دلتون می‌خواد راجع هر کدوم از اینا بیشتر بدونید، من (جناب کنت سی دادز) یه ورکشاپ جاوا اسکریپت دارم که وقتی توی پی پال کار می‌کردم ضبط و منتشرش کردم که ممکنه یاری دهنده باشه: ES6 and Beyond Workshop at Paypalموفق باشید!</description>
                <category>جلال حامد</category>
                <author>جلال حامد</author>
                <pubDate>Thu, 09 Sep 2021 23:30:00 +0430</pubDate>
            </item>
            </channel>
</rss>