<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های Eddie Cooro</title>
        <link>https://virgool.io/feed/@eddiecooro</link>
        <description>ادی ام. عاشق جاوااسکریپت و فعال ری‌اکت. علاقه به R&amp;D دارم و اینجا از چیزایی که برام جالبن میگم. اگه هروقت هرکمکی از دستم برمیومد بهم بگید 3&gt;</description>
        <language>fa</language>
        <pubDate>2026-06-16 18:33:14</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/12767/avatar/ag6DQu.png?height=120&amp;width=120</url>
            <title>Eddie Cooro</title>
            <link>https://virgool.io/@eddiecooro</link>
        </image>

                    <item>
                <title>کی باید به setState تابع پاس بدیم؟</title>
                <link>https://virgool.io/iran-react-community/when-to-pass-function-to-use-state-erserk2a0x8k</link>
                <description>تابع setState رو توی ری‌اکت به دو شکل میتونیم استفاده کنیم.۱- با پاس دادن مقدار، و  ۲- با پاس دادن تابع.تو حالت اول مقداری که پاس میدیم جایگزین مقدار قبلی استیت میشه (توی class component مقدار باید object باشه و با object قبلی merge میشه) و تو حالت دوم، ری‌اکت آخرین مقدار state رو بعنوان ورودی به تابعی که بهش دادیم میده و از مقدار خروجی تابع بعنوان مقدار برای setState کردن، مشابه حالت اول، استفاده می‌کنهحالا سوالی که پیش میاد اینه:چه زمانی ما نیاز داریم که به setState تابع پاس بدیم؟ و چرا؟بعنوان یه حکم همیشگی، میشه گفت که هروقت مقدار جدید state به مقدار قبل از خودش وابسته بود، باید از function برای setState استفاده کنیم. ینی چی؟ به این مثال دقت کنید: setValue(value + 1);توی این مثال مقدار جدید value واضحا به مقدار قبلی خودش بستگی داره. ما در حال حاضر یه مقداری رو بعنوان value داریم که مثلا برابر ۱ هست و با استفاده از اون می‌خوایم value جدید که ۲ میشه رو بسازیم. اینجور مواقع بهتره که از function بجای پاس دادن مستقیم مقدار استفاده کنیم:setValue(value =&gt; value + 1);&quot; /&gt; value + 1);&quot; /&gt;setValue(value =&gt; value + 1);اینجا ما بجای اینکه مستقیم از value استفاده کنیم، یه تابع به setValue پاس دادیم. ری‌اکت آخرین مقدار value رو به تابع ما پاس میده و مقداری که return میشه رو داخل استیت ست می‌کنه.برای این حکم همیشگی رو رعایت میکنیم، که اگر ۱۰۰٪ مواقع کدمون رو اینجوری بنویسیم، می‌تونیم مطمئن باشیم که هیچوقت هیچ مشکلی پیش نمیاد. هرچند که فقط ۲۰٪ مواقع مشکل‌ساز باشن.این ۲۰٪ مواقع کی‌ها هستند؟این ۲۰٪ مواقع دردسرساز، که ما رو مجبور به استفاده از function برای setState می‌کنند، به دو دسته تقسیم میشن.دسته اول:همه ما با نکته زیر توی جاوااسکریپت آشناییم. ولی انگار وقتی وارد ری‌اکت میشیم فراموشش میکنیم.مفهوم closure در جاوا‌اسکریپتما این رو میدونیم و مطمعنیم که firstLogger رو هروقت صدا بزنیم مقدار 0 رو داخل کنسول چاپ می‌کنه. و مهم نیست که بعد از دفعه اول، تابع getLogger رو با مقادیر دیگه‌ای هم صدا زده باشیم یا نه. چرا؟ چون تابع firstLogger مقدار 0 رو داخل closure خودش ذخیره کرده. حالا مثال زیر رو ببینید:مفهوم closure در function componentتوی این مثال، ما دوتا دکمه روی صفحه داریم که کلیک بر روی یکیشون مقدار a رو لاگ میگیره و کلیک بر روی اونیکی مقدار a رو به 1 تغییر میده. حالا اگه اول روی دکمه Log کلیک کنیم، میبینیم که عدد 0 لاگ گرفته میشه. ولی اگه روی دکمه Inc و سپس Log کلیک کنیم، انتظار داریم عدد 1 لاگ گرفته بشه اما چیزی که میبینیم همون عدد 0 هست. چرا؟دلیلش ساده‌اس. ما از useCallback استفاده کردیم و بعنوان dependencies array بهش یه آرایه خالی دادیم (اگر نمی‌دونید dependencies array چیه اینجا رو بخونید). درواقع با پاس دادن dependencies array خالی به useCallback، داریم به ری‌اکت میگیم که فرقی نمی‌کنه که چه اتفاقی میافته، تابع logger باید همیشه همون تابعی که دفعه اول ساخته شده بمونه. ینی همون تابع firstLogger توی مثال قبلی. توی مثال قبلی اینکه دوباره تابع getLogger رو با مقدار جدید صدا میزدیم، باعث میشد که مقداری که firstLogger لاگ میگیره عوض بشه؟ نه. پس توی این مثال هم اینکه کامپوننت رو با استیت جدید رندر بکنیم، باعث نمیشه تابعی که دفعه اول ساخته شد مقدار جدیدی رو لاگ بگیره. و useCallback داره باعث میشه که همیشه همون تابع اولیه برگرده. درست کردنش راحته:رفع مشکل با اضافه کردن متغیرهای مورد استفاده در closure به dependency arrayاینجوری میتونیم بگیم که هروقت مقدار a عوض شد، useCallback تابع جدیدی که ساخته میشه رو بهمون پس بده. یعنی انگار که توی مثال جاوااسکریپتی بالا، همیشه آخرین مقدار برگشتی از getLogger رو داشته باشیم.خب برگردیم سر بحث خودمون. بیاید فرض کنیم بجای تابع logger همچین چیزی داریم:مشکل closure در function componentاین کد درست کار نمی‌کنه. توی مثال قبل یادتونه که تابع logger همیشه 0 رو لاگ میگرفت؟ توی این مثال هم، این تابع مقدار count = 0 رو حفظ کرده و هر دفعه که increment رو صدا میزنیم، انگار که داریم میگیم:دلیل بوجود آمدن مشکل closure در function componentینی همیشه داریم مقدار 1 رو بعنوان count ست می‌کنیم. برا همین دکمه Inc بعد از بار اول که مقدار count رو 1 می‌کنه، بنظر میرسه که دیگه کار نمی‌کنه.راه حل چیه؟ ساده‌اس. دوتا کار میشه کرد، یکی اینکه مثل حالت قبل، به ری‌اکت بگیم که هردفعه یه تابع جدید برای increment بسازه:حل مشکل closure با اضافه کردن count به dependency arrayاینجوری خیالمون راحته که هردفعه که کامپوننت با مقدار جدیدی برای count دوباره رندر میشه، یه تابع جدید ساخته میشه و این تابع جدید بعنوان  روی button ست میشه.و راه حل دوم اینه که بجای خوندن count از closure، به ری‌اکت بگیم خودش آخرین مقدار count رو بهمون بده:حل مشکل closure با پاس دادن function به تابع setStateاینجوری فقط یک بار تابع increment رو میسازیم ولی هربار که صداش میزنیم، آخرین مقدار count رو میگیره و یک واحد بهش اضافه می‌کنه.البته ترجیح من برای ساخت همچین تابعی اینه:(درسته که وقتی از useCallback استفاده نمی‌کنیم خیالمون راحته که همیشه آخرین مقدار count رو داخل closure داریم، اما قانون 80/20 یادتون نره و از function استفاده کنید) دسته دوم:اگر مورد بالا رو توی function component ها رعایت کنید، خودکار درمقابل دسته دوم هم مقاوم شدید. برای همین این دسته رو برای class component ها بررسی میکنیم.فرض کنید همچین کامپوننتی داریم: ?کلاس کامپوننت خودکار همه چیز رو پیچیده و طولانی می‌کنهاین کامپوننت قراره در وهله اول، یه آرایه از userها رندر کنه. یه prop به اسم shouldTrackCount هم میگیره که اگه true باشه تعداد userها رو هم داخل state نگه می‌داره (بچه‌های تو خونه قول بدید این کار رو نکنید) (فقط برای آموزش) (Don&#x27;t do this at home) (بجاش همون this.state.users.length رو داخل رندر استفاده کنید)قسمت هیجان انگیز ماجرا توی تابع addUser اتفاق میافته. تو این تابع ۲ تا setState داریم. اولی یه یوزر جدید به آرایه یوزرها اضافه می‌کنه، و دومین setState تعداد جدید یوزرهارو حساب می‌کنه و setState می‌کنه.اما این تابع درست کار نمی‌کنه. چرا؟ بخاطر batching.درواقع ری‌اکت setStateها رو بصورت sync انجام نمیده. یعنی چی؟ اگه تابع addUser رو به این شکل بازنویسی کنیم:اگر بلافاصله بعد از setState سعی کنیم که مقدار state رو لاگ بگیریم متوجه میشیم که تغییر نکرده.میبینید که هیچوقت user ای که اخیرا به state اضافه شده توی log دیده نمیشه. چرا؟ چون ری‌اکت setState رو همون لحظه انجام نمیده. درواقع با صدا زدن setState، ما ری‌اکت رو از تغییر باخبر می‌کنیم. اما تصمیم اینکه کی این تغییر انجام بشه با ری‌اکته و ری‌اکت معمولا ترجیح میده که بعد از تموم شدن تابع تغییرات رو اعمال کنه. چرا؟ چون اگه همون لحظه این‌کار رو بکنه، مجبوره یه دور درخت رو با استیت جدید رندر کنه و بعد اگه تو خط پایین یه setState دیگه داشته باشیم، مجبور میشه دوباره کل رندر کردن درخت رو تکرار کنه. برا همین صبر می‌کنه تا اجرای تابع تموم بشه، بعد همه تغییرات رو همزمان انجام میده.تو مثال addUser اگر فرض کنیم که داریم:بیاید روی object هایی که به setState پاس میدیم اسم بذاریمکاری که ری‌اکت درنهایت انجام میده شبیه به اینه:ری‌اکت setState های مارو تبدیل به همچین چیزی می‌کنهکه معادله با:شکل باز شده نتیجه setState های ماو به وضوح میتونیم ببینیم که this.state.users هنوز به مقدار قبلی آرایه users اشاره می‌کنه، چرا که درحال اجرای setState هستیم و هنوز تغییر استیت انجام نشده و درنتیجه length آرایه users هم همیشه مقدار قدیمی رو نشون میده.و راه حل این مشکل بازهم مثل همیشه استفاده از function برای setState عه. اینجوری به ری‌اکت میگیم که برای حساب کردن count به آخرین مقدار state نیاز داریم و ری‌اکت هم این مقدار رو بعنوان ورودی تابعمون بهمون میده.حل مشکل obsolete state با پاس دادن function به setStateوالسلام.(نکته اضافی)شاید متوجه شده باشید که نکته دوم، ینی batch کردن setState ها، همیشه اتفاق نمیافته. دلیلش اینه که ری‌اکت درحال حاضر یسری محدودیت‌ها برای انجام دادن این‌کار داره و فقط setState‌های داخل تابع‌هایی رو batch می‌کنه که توسط ری‌اکت فراخوانی میشن. بعنوان مثال تابع  تابعیه که ما به ری‌اکت میدیم و ری‌اکت هروقت که برروی المنت کلیک بشه صداش میزنه. و یا تابع componentDidMount تابعیه که توسط ری‌اکت صدا زده میشه و درنتیجه همه setStateهای داخلش باهمدیگه batch میشن.اما اگه کدی مثل شکل زیر داشته باشیم:ری‌اکت فقط setState هایی که توی تابع‌هایی که توسط ری‌اکت اجرا میشن رخ داده‌اند رو batch می‌کنهمتوجه میشیم که این دو setState بجای اینکه باهمدیگه batch بشن و منجر به ۱ رندر بشن، جدا جدا اعمال میشن و درخت ری‌اکت ۲ بار رندر میشه. دلیلش اینه که باوجود اینکه تابع componentDidMount توسط ری‌اکت صدا زده میشه، ولی تابع داخل then بصورت async اجرا میشه و در زمانی در آینده، توسط خود انجین جاوااسکریپت (و توسط Promise) صدا زده میشه. بنابراین کنترلش دست ری‌اکت نیست.درواقع کاری که ری‌اکت می‌کنه شبیه به اینه:کاری که ری‌اکت موقع صدا زدن تابع‌ها انجام میدهو این توی مثال بالا کار نمی‌کنه چون then بعد از صدا زده شدن endBatching صدا زده میشه و درنتیجه setState ها بصورت batch نشده اتفاق میافتن.راه حل چیه؟ درحال حاضر ری‌اکت یه تابع به اسم unstable_batchedUpdates اکسپورت می‌کنه که به ما اجازه میده خودمون دستی به ری‌اکت بگیم که setState هارو batch کنه.میتونیم با استفاده از unstable_batchedUpdates همه setState هامون رو batch کنیممیتونیم پیاده‌سازی این تابع رو معادل زیر فرض کنیم:پیاده‌سازی فرضی تابع unstable_batchedUpdatesاما توی استفاده ازش بشدت محتاط باشید. این تابع همونطور که از اسمش معلومه unstable هست و ممکنه تو هر ورژنی حذف بشه یا تغییر کنه و باعث بشه ارتقا دادن ری‌اکتتون سخت‌تر از چیزی بشه که باید باشه.ولی چرا ری‌اکت باید بخواد این تابع رو حذف کنه؟ دلیلش اینه که بعد از ریلیز شدن ورژن جدید ری‌اکت، با قابلیت concurrent mode (که درحال حاضر میتونید تحت فلگ experimental تستش کنید)، ری‌اکت اونقدری باهوش میشه که بتونه setState های دستی ما رو هم تشخیص بده و همرو با هم batch کنه و دیگه نیازی به این شکل استفاده کردن از unstable_batchedUpdates نخواهد بود.اما اینکه ری‌اکت چجوری میتونه setState های ما رو متوجه بشه؟ موضوع یه مقاله دیگه‌اس :)شاد و موفق باشید و امیدوارم از این به بعد توی setStateهاتون بیشتر از function استفاده کنید.دیگر مقالات من: https://vrgl.ir/gwLl7  https://vrgl.ir/2LzT9  https://vrgl.ir/WWPQ1 </description>
                <category>Eddie Cooro</category>
                <author>Eddie Cooro</author>
                <pubDate>Mon, 04 May 2020 00:06:04 +0430</pubDate>
            </item>
                    <item>
                <title>داخل هوک‌ها چه خبره؟ (قسمت اول)</title>
                <link>https://virgool.io/iran-react-community/%D8%AF%D8%A7%D8%AE%D9%84-%D9%87%D9%88%DA%A9%D9%87%D8%A7-%DA%86%D9%87-%D8%AE%D8%A8%D8%B1%D9%87-%D9%82%D8%B3%D9%85%D8%AA-%D8%A7%D9%88%D9%84-zalkruwq3rci</link>
                <description>تابحال به این فکر کردید که هوک‌های ری‌اکت چجوری کار می‌کنن؟اینکه چیکار می‌کنن نه، ده‌هزار تا مقاله راجب چیکار کردنشون موجوده، اینجا میخوایم راجب این صحبت کنیم که هوک‌های ری‌اکت، چجوری کار می‌کنن و در نتیجه، میتونیم اینکه چیکار می‌کنن رو بهتر درک کنیم.برا فهمیدن این‌که هوک‌ها چجوری کار می‌کنن، باید کلی توی source ری‌اکت بگردیم. برای این‌که بحث طولانی‌ نشه، از بعضی قسمت های DEV و نکات خارج از هوک‌ها صرف نظر می‌کنیم، و در نهایت توی دو بخش source هوک‌ها رو بررسی می‌کنیم.بخش اول، که این مقاله‌اس، در قالب ۴ ویدیو به یسری مقدمات میپردازه، چیزهایی که باید بلدشون باشیم تا بتونیم پیاده‌سازی هوک‌هارو بخونیم و بفهمیم.توی ویدیوی اول، میگردیم ببینیم لابلای اینهمه کد ری‌اکت، هوک‌ها کجای قضین، و برای فهمیدنشون کدوم فایل‌ها رو باید بررسی کنیم.توی ویدیوی دوم، مهم ترین تابع اون فایل، ینی تابع renderWithHooks رو میخونیم، با مفاهیم  current fiber و workInProgress fiber آشنا میشیم، میبینیم که هوک‌ها کجا ذخیره می‌شن و کیه که وظیفه مدیریت کردن تابع‌های useState و useReducer و سایر هوک‌ها رو بر عهده داره.توی ویدیوی سوم، با data structure ای که هوک‌ها توش ذخیره میشن آشنا میشیم. دوتا linked list به اسم های currentHooks و workInProgressHooks. و می‌بینیم که ری‌اکت چجوری با استفاده از تابع‌های mountWorkInProgressHooks و updateWorkInProgressHooks باهاشون ارتباط برقرار می‌کنه.و توی آخرین ویدیو، یه مثال از ری‌اکت واقعی می‌بینیم. سعی می‌کنم داخل internal هاش سرک بکشیم و یه نگاهی به چیزهایی که طی ویدیوهای قبلی بررسی کردیم بندازیم.پس بریم که داشته باشیم. https://www.aparat.com/v/Q1gfR  https://www.aparat.com/v/vLTDN  https://www.aparat.com/v/HuUv6  https://www.aparat.com/v/GmjvI لینک قسمت اوللینک قسمت دوملینک قسمت سوملینک قسمت چهارم</description>
                <category>Eddie Cooro</category>
                <author>Eddie Cooro</author>
                <pubDate>Tue, 29 Oct 2019 17:16:27 +0330</pubDate>
            </item>
                    <item>
                <title>آیا Svelte جایگزین Vue میشود؟</title>
                <link>https://virgool.io/@eddiecooro/%D8%A2%DB%8C%D8%A7-svelte-%D8%AC%D8%A7%DB%8C%DA%AF%D8%B2%DB%8C%D9%86-vue-%D9%85%DB%8C%D8%B4%D9%88%D8%AF-nrc9lscpycck</link>
                <description>اگه تو جامعه فرانت فعال باشید، چندوقتیه که اسم Svelte از همه جا شنیده میشه.اما چرا؟ چی Svelte رو متمایز می‌کنه، و چجوری تونسته تو بازار فعلی فریم‌ورک های فرانت، که چندتا ابر غول دارن باهم مبارزه می‌کنن، جاش رو پیدا کنه؟تو ویدیوی اول یه کوچولو داخل سورس Svelte سرک می‌کشیم که ببینیم چه کاری رو متفاوت از بقیه فریم‌ورک ها انجام میده که مورد توجه قرار گرفته، و اینکه میگه من compilerام یعنی چی، و تو ویدیوی دوم با استفاده ازش یه html/css/js ادیتور با preview خیلیییییییییییی ساده می‌سازیم که نتیجه‌اش رو میتونید اینجا ببینید.ویدیوی اول (لینک): https://www.aparat.com/v/qtYjU ویدیوی دوم (لینک): https://www.aparat.com/v/K1eiB دیگر مقالات من: http://vrgl.ir/gwLl7  http://vrgl.ir/2LzT9  http://vrgl.ir/WWPQ1 </description>
                <category>Eddie Cooro</category>
                <author>Eddie Cooro</author>
                <pubDate>Sun, 15 Sep 2019 20:48:20 +0430</pubDate>
            </item>
                    <item>
                <title>اگر React و Chrome بچه داشتند. (بخش اول، ژن React)</title>
                <link>https://virgool.io/iran-react-community/%D8%A7%DA%AF%D8%B1-react-%D9%88-chrome-%D8%A8%DA%86%D9%87-%D8%AF%D8%A7%D8%B4%D8%AA%D9%86%D8%AF-%D8%A8%D8%AE%D8%B4-%D8%A7%D9%88%D9%84-%DA%98%D9%86-react-a6wtjllkzsxo</link>
                <description>خیلی سریع میرم سر اصل مطلب، تو این مقاله میخوام راجب API ای صحبت کنم که حاصل همکاری ری‌اکت و کرومه، web scheduling API.اما قبلش یکم پیش زمینه نیازه، همه چیز از یه پکیج شروع شد: پکیج Schedulerپکیج Scheduler توسط تیم فیسبوک ساخته شده، داخل ریپازیتوری خود‌ ری‌اکت maintain میشه و قراره تو زمینه Cooperative Scheduling بهمون کمک کنه. این پکیج بشدت داخل سورس React استفاده میشه و همین الان هم می‌تونیم اون رو با دستور npm i scheduler نصب کنیم. چی؟ Cooperative Scheduling چیه؟هممون میدونیم که جاوااسکریپت یدونه Thread بیشتر نداره، یعنی در لحظه فقط ۱ کار میتونه انجام بده. و داخل مرورگر علاوه بر اجرای جاوااسکریپت، تقریبا همه چیزهای دیگه‌ی وبسایت از validate کردن فرم‌ها گرفته تا ریکوئست زدن به سرور و به حرکت در‌آوردن انیمیشن ها و پخش گیف و ویدیو و اسکرول(در بعضی موارد) و حتی سلکت کردن متن بر عهده همین یک Threadعه. Cooperative Scheduling بهمون کمک میکنه از Threadمون نهایت استفاده رو ببریم.درواقع کانسپت Cooperative Scheduling (یا cooperative multitasking) به معنی &quot;برنامه ریزی مشارکتی&quot; ? از علوم کامپیوتر قرض گرفته شده و تو حوزه سیستم‌های عامل‌ از مدت ها پیش حضور داشته (قبل از اختراع ویندوز یا حتی لینوکس) و خیلی شناخته شده‌اس. قضیه اینه که میخوایم همین یدونه ترد رو طوری &quot;برنامه ریزی&quot; کنیم که همه بطور &quot;مشارکتی&quot; ازش استفاده کنن. نقل قول از ویکیپدیا:Cooperative multitasking, is a style of computer multitasking in which processes voluntarily yield control periodically or when idle or logically blocked in order to enable multiple applications to be run concurrently.یعنی چی؟ فرض کنید cpu لپتاپ من فقط یک core داشته باشه. اما من بعد از بالا اومدن سیستم عامل،‌ میخوام همزمان هم تلگرامم رو باز داشته باشم، هم مرورگرم رو. اگه به لطف تکنیک هایی مثل همین cooperative scheduling نبود (تو سیستم عامل های متداول از تکنیک دیگه ای به اسم preemptive multitasking استفاده میشه)، همچین چیزی امکان نداشت. چون process تلگرام به محض اینکه باز میشد، cpu رو مشغول میکرد و تا زمانی که بسته نشده به هیچ برنامه دیگه‌ای اجازه نمیداد از منابع سیستم استفاده کنه.اما این تکنیک ها چجوری مشکل رو حل می‌کنن؟ با ایجاد کردن &quot;توهم&quot; همزمانی. به هرکدوم از برنامه‌های ما یه زمانی برای استفاده از cpu اختصاص میدن، و بعد کنترل رو به برنامه بعدی پاس میدن. اینجوری در هر ثانیه چندبار کنترل cpu بین اپ های مختلف جابجا میشه و اینطور بنظر میرسه که بطور همزمان دارن کار میکنن، ولی درواقعیت اینطور نیست. همون یک ترد موجود بین اپ های مختلف تقسیم شده، و سیستم عامل میتونه ضمن تقسیم کردن منابع، تصمیم بگیره به اپی که تو حالت focus عه اولویت بیشتری بده، یا اولویت اپی که minimize شده رو کم کنه، بدون اینکه یوزر یا دولوپر اون اپ ها متوجه چیزی بشن (ری‌اکت قراره در آینده با concurrent mode اینکار رو برامون انجام بده)باشه. ولی مگه مرورگر سیستم‌عامله؟بله.مرورگر سیستم عاملیه بر روی سیستم‌عامل ها (شاید در‌آینده مستقل‌تر ببینیمش?). درواقع مرورگر همون چیزیه که یه زمان James Gosling با ساختن JVM آرزوش رو داشت. یه runtime جهانی،‌ فارغ از سخت‌افزار و نرم‌افزار موجود.و درنتیجه برای سریع‌تر کردن برناممون، به تکنیک‌های مشابه نیاز داریم. و اینجاست که نقش scheduler مشخص میشه.نقل قول از داکیومنت scheduler:This is a package for cooperative scheduling in a browser environment.اوکی، پس این پکیج قراره تو زمینه cooperative scheduling داخل مرورگر بهمون کمک کنه. اما چجوری؟قبل از اینکه جلوتر بریم بذارید یه نکته خیلی مهم رو ذکر کنم:The public API for this package is not yet finalized.تیم ری‌اکت همچنان دارن روی این پکیج کار می‌کنن و هرچند استفاده ازش برای خودشون امنه،‌ ولی اگه شما هم دوست داشتید ازش استفاده کنید، یا fork خودتون رو بسازید و یا از experiment کردن جلوتر نرید.برای دستیابی به یه CPU آزاد که در اون هر تسکی فارغ از نژاد و ملیتش بتونه به‌ راحتی کارهاش رو انجام بده (?) نیازمند انجام ۲ تا کاره:۱- همه تسک‌هامون رو تا حد امکان کوچیک کنیم، و اگه کاری هست که انجام شدنش زمان زیادی می‌بره، یا از تکنیک هایی مثل WebWorker استفاده کنیم و یا اون رو به کارهای کوچیکتر تقسیم کنیم.۲- بتونیم به تسک‌های مختلف اولویت‌های مختلف بدیم (اونقدرام فارغ از نژاد نیست گویا ?)، بعنوان مثال کاربر بعد از کلیک کردن روی یه دکمه، برای دیدن نتیجه تعاملش مجبور نباشه منتظر بمونه تا ما رندر کردن یه بخش دیگه از صفحه رو کامل تموم کنیم، یا عدد دو میلیاردم فیبوناچی رو حساب کنیم.پکیج Scheduler چجوری کمکمون میکنه؟پکیج Scheduler فووووووووووووق العاده ساده‌اس(در عین نبوغ) و از سه تا فایل اصلی تشکیل میشه:1- /packages/scheduler/src/Scheduler.jsاین فایل API پکیج scheduler رو شامل میشه و بخش اعظم لاجیک اولویت بندی‌ها تو این فایل پیاده شده.2- /packages/scheduler/src/forks/SchedulerHostConfig.default.jsکدهای لازم برای ارتباط Scheduler با پلتفرمی که روش اجرا میشه، (مرورگر یا نود) و زمان‌بندی فریم‌های برنامه داخل این فایل قرار دارن.3- /packages/react-reconciler/src/SchedulerWithReactIntegration.jsیه لایه ارتباطی خیلی نازک بین پکیج scheduler و react عه، برای اینکه کدها  decoupled بمونن و افراد خارج از react هم بتونن از scheduler استفاده کنن.بریم ببینیم این فایل‌ها دقیقا چیکار میکنن:Scheduler.jsمهم‌ترین تابعی که از این فایل اکسپورت میشه(که مهم‌ترین تابع کل پکیج هم هست) فانکشن scheduleCallback عه. این تابع ۳ تا ورودی میگیره: priorityLevel که اولویت کار یا همون تابعی که داریم schedule میکنیم رو مشخص میکنه، callback که تابعیه که قراره کارمون رو انجام بده، و options که یه آبجکته با دوتا فیلد delay و timeout که هردو آپشنالن و برای ما خیلی مهم نیستن.priorityLevel می‌تونه یکی از مقادیر زیر رو داشته باشه:ImmediatePriority, UserBlockingPriority, MediumPriority, LowPriority و IdlePriority(به ترتیب از اولویت بالا به پایین)بعد از گرفتن ورودی‌ها، تابع scheduleCallback بلافاصله برای priorityLevel ای که بهش دادیم، با استفاده از تابع timeoutForPriorityLevel مقدار timeout رو حساب میکنه. کد این تابع تقریبا شبیه قطعه کد زیره:سورس کد تابع timeoutForPriorityLevelو بعد با استفاده از فرمول زیر، expirationTime رو حساب میکنه:const expirationTime = getCurrentTime() + timeout;اما این ینی چی؟ آیا معنیش اینه که اگه تسکی با اولویت Normal داشته باشیم، بعد از 5 ثانیه انجام میشه؟به هیچ وجه.همه تسک‌ها، با توجه به اولویتشون، در اولین فرصتی که پیدا کنن انجام میشن; اما timeout برای جلوگیری از اتفاقی به اسم starvation ساخته شده.برای اینکه متوجه بشیم starvation چیه باید جلوتر بریم تا ببینیم دقیقا چجوری از timeout استفاده شده.تابع scheduleCallback بعد از محاسبه timeout،‌ برای callback ما یه آبجکت به نام task میسازه. مهم‌ترین فیلد های این آبجکت چهارتا فیلد callback, priorityLevel, startTime و expirationTime ان. و بعد از ساخته شدن هر تسک، اون رو داخل یه minHeap به اسم timerQueue قرار میده و expirationTime رو بعنوان sortIndex ست میکنه.(اگه نمیدونید داده‌ساختار minHeap چیه این منبع میتونه براتون مفید باشه. ولی می‌تونید اینجوری تصور کنید که minHeap یه آرایه‌اس، که همیشه از بزرگ به کوچیک مرتب شده، درنتیجه تو مثال ما که sortIndex برابر expirationTimeعه، همیشه اولین عضو آرایه عضویه که کوچیکترین expirationTime رو داره، ینی از همه تسک‌ها زودتر expire میشه)بعد از اضافه کردن task به heap،‌ تابع scheduleCallback یکی از تابع های فایل SchedulerHostConfig به اسم requestHostCallback رو صدا میزنه و تابعی به اسم flushWork رو بهش ورودی میده.فعلا بیاید اینطور &quot;فرض&quot; کنیم که این تابع صرفا همچین کاری می‌کنه:function requestHostCallback(fn) {
    setTimeout(fn, 0);
}پس اگه ما بهش flushWork رو ورودی بدیم، بلافاصله توی فاز بعدی timer ها تابع مارو صدا میزنه.خوشبختانه کد واقعی requestHostCallback به این سادگی نیست (پایینتر دقیق بررسیش می‌کنیم) و دوتا آرگومان به flushWork ما ورودی میده: اولی hasTimeRemaining که مشخص می‌کنه آیا هنوز توی این فریم زمان داریم یا نه، و دومی initialTime که timestamp (یا به عبارت دقیق‌تر DOMHighResTimestamp) زمان فعلی برنامه، در لحظه اجرا شدن تابع رو مشخص می‌کنه. کاری که تابع flushWork می‌کنه اینه که تابع workLoop رو صدا می‌زنه و اونجا عضو ریشه minHeap (عضو با کمترین expirationTime) رو برمیداره، توی متغیر task میریزدش و چک می‌کنه ببینه آیاtask.expirationTime &lt;= initialTimeهست یا خیر. (دقت کنید کدهای واقعی کمی تفاوت دارن، ولی نتیجه یکسانه و من سعی می‌کنم ساده ترین حالت رو توضیح بدم)اگر شرط بالا برقرار باشه، callback تسک صرف‌نظر از اینکه آیا hasTimeRemaining = true هست یا نه صدا زده میشه. و چک کردن ریشه minHeap انقدر تکرار میشه تا دیگه تسکی که از expirationTime اش گذشته باشه داخل minHeap وجود نداشته باشه یا بعبارتی همه تسک های expire شده انجام شده باشن.بعد workLoop یکی دیگه از توابع SchedulerHostConfig به اسم shouldYieldToHost رو صدا میزنه تا چک کنه آیا هنوز هم وقت اضافه‌ای برای انجام کارهامون داریم؟ اگر جواب مثبت بود دوباره سراغ minHeap میره و عضو ریشه‌اش رو برمیداره و callback متناظرش رو صدا می‌زنه. این عملیات هم تا اونجایی ادامه پیدا می‌کنه که یا دیگه تسکی داخل minHeap وجود نداشته باشه، و یا تابع shouldYieldToHost مقدار false برگردونه.در این حالت بسته به اینکه آیا هنوز تسکی داخل minHeap داریم یا نه،‌ یکی از دو مقدار true یا false رو ریترن می‌کنیم و درواقع به SchedulerHostConfig میگیم که آیا درآینده بازهم کاری برای انجام دادن داریم یا نه.چیزی که تااینجا از رفتار تابع workLoop متوجه شدیم اینه که اگه timeout یه تسک Normal برابر ۵ ثانیه‌اس، معنیش این نیست که تابع ما بعد از ۵ ثانیه اجرا میشه،‌ بلکه معنیش اینه که اگر بیشتر از ۵ ثانیه گذشته باشه و تابع ما هنوز فرصت اجرا شدن پیدا نکرده باشه، scheduler در اولین فرصت تابع ما (و همه توابع expire شده) رو صرف‌نظر از اینکه آیا اجراشون باعث دیرتر جواب دادن به interaction های کاربر، یا کمی لگ زدن انیمیشن‌ها میشه یا نه، اجرا می‌کنه.بعنوان مثال اگه تابعی با اولویت NormalPriority داشته باشیم و scheduler کار دیگه‌ای نداشته باشه، تابع ما بلافاصله (درواقع بعد از اجرا شدن setTimeout فرضیمون)‌ اجرا میشه. اما اگه سر scheduler شلوغ باشه و ۱۰ تا تابع با اولویت UserBlockingPriority داشته باشه، NormalPriority باید صبر کنه تا یا 1) همه اون‌ها انجام شن یا 2) انقضاش بگذره، تا همشون پشت سرهم داخل فریم فعلی شروع به اجرا شدن کنن. که در‌اینصورت معنیش اینه که همه توابع UserBlocking ما هم از انقضاشون گذشته (چون توی minHeap بالاتر از Normal ما قرار داشتن و درنتیجه expirationTime کوچکتری دارن)تو مثال بالا اگه حین پردازش تسک های UserBlocking، یه تسک Immediate به scheduler مون اضافه بشه، چون timeout اش برابر منفی یکه، تو minHeap بالاتر از بقیه تسک های UserBlocking قرار می‌گیره و قبل از اون‌ها انجام میشه. یا اگه بعد از پردازش UserBlocking ها و قبل از پردازش تسک Normal مون،‌ یه تسک UserBlocking جدید به minHeap اضافه بشه، به احتمال خیلی زیاد جلوتر از تسک Normal ای که درحال حاضر توی minHeap هست قرار میگیره (مگر اینکه تا expirationTime تسک Normal ما کم‌تر از ۲۵۰ میلی ثانیه باقیمونده باشه)خب این ساختاری که توضیح دادم، هیچوقت مشکل Starving براش پیش نمیاد. یعنی چی؟ سیستمی رو فرض کنید که تسک هارو فقط به ترتیب اولویت انجام بده. مثلا فقط و فقط به شرطی تسک Normal رو انجام بده که هیچ تسک UserBlocking ای وجود نداشته باشه. توی این سیستم به مشکل starving میخوریم،‌ ینی ممکنه حالتی پیش بیاد که مثلا هر تسک UserBlocking،‌ یه تسک UserBlocking دیگه رو schedule کنه. پس تا ابد تسک های UserBlocking خودشون رو میسازن و هیچوقت نوبت به تسک Normal ما نمیرسه. اما تو سیستم فعلی scheduler، حتی اگه همچین اتفاقی بیافته، تسک Normal مابالافاصله بعد از اینکه به فاصله کم‌تر از ۲۵۰ میلی ثانیه تا expiration اش برسه، از همه تسک های UserBlocking ای که بعد از این schedule میشن اولویت بالاتری پیدا می‌کنه و قطعا انجام میشه. یا بعبارتی، هیچوقت مشکل starving پیش نمیاد.امیدوارم خوب مفهوم رو منتقل کرده باشم.کوچیک کردن تسک هاتا الان چندبار ذکر کردیم، یکی از بخش‌های طراحی cooperative scheduling،‌ اولویت بندی کردن task هاست. اما پکیج scheduler تو این موضوع چجوری بهمون کمک می‌کنه؟مثال زیر رو ببینید: (کدسندباکس)https://codesandbox.io/s/react-scheduler-fibo-animation-hfu8xتو این مثال یه فانکشن داریم که سعی می‌کنه ۲۰۰ امین عدد فیبوناچی رو با یه الگوریتم عادی O n حساب کنه، اما از عمد داخل هر بار اجرای forای که فیبوناچی رو حساب می‌کنه، فانکشن delay رو صدا زدم که یه while خالی رو ۵۰ میلیون بار میچرخه و درنتیجه الگوریتم رو بشدت کند می‌کنه.همزمان با این فانکشن، تابع animate رو صدا زدیم که با استفاده از javascript مربع قرمز رنگی که داخل صفحه داریم رو animate می‌کنه، روش کار اینجوریه که lastTime رو ذخیره می‌کنیم، بعد توی هر تیک requestAnimationFrame مقدار زمانی که از lastTime گذشته رو پیدا می‌کنیم و حساب می‌کنیم که مربعمون چند پیکسل باید جابجا بشه و درآخر box.style.left رو با مقدار بدست اومده ست می‌کنیم.اما حالا اگه دقت کنید، متوجه میشید که تا قبل از محاسبه فیبوناچیمون، مربع از جاش تکون نمیخوره. دلیلش واضحه: تابع فیبوناچی کل منابع سیستم مارو گرفته و بهمون اجازه نمیده که کد دیگه‌ای اجرا کنیم، در نتیجه،‌ نه فقط انیمیشن، بلکه کل سایت تو این مدت freeze میشه.قطعا این اتفاقی نیست که دوست داشته باشیم هرروز تو سایتمون بیافته.حالا اجرای فانکشن blockingFibo رو با fibo جایگزین کنید.(خط ۷۲) بعد از ریلود متوجه میشید که حتی درحین محاسبه عدد فیبوناچی هم، انیمیشن تقریبا smooth پخش میشه (اگر هنوز لگ دارید مشکل از بیش از حد طولانی بودن while پنج میلیون تاییه، که احتمالا روی دیوایستون نمیشه طی مدت زمان کم‌تر از ۱۰۰ میلی ثانیه اجراش کرد)چجوری موفق شدیم اینکار رو بکنیم؟ برای دستیابی به این نتیجه از ۳ تا API مختلف scheduler استفاده کردیم.1- unstable_scheduleCallbackهمونجوری که می‌بینید داخل فانکشن fibo یه تابع داریم به اسم work، که این تابع رو خودمون صدا نکردیم،‌در عوض رفرنس تابع رو برای scheduleCallback فرستادیم و اجازه دادیم scheduler با استفاده از minHeap اش بهش رسیدگی کنه. ضمنا priorityLevel رو هم روی Idle ست کردیم،‌ چون تسک مهمی نیست و میخوایم هروقت مرورگر کار دیگه‌ای برای انجام دادن نداشت، یکم وقت هم روی حساب کردن فیبوناچی بذاره پس این لول براش مناسبه.2- unstable_shouldYieldاین تابع هم یکی از تابع هاییه که از خود Scheduler.js اکسپورت شده و توی کدش اول چک می‌کنه ببینه آیا تسکی با اولویت بالاتر از تسکی که الان درحال انجام دادنش هستیم داریم،‌ یا نه. درصورتی که تسکی با اولویت بالاتر داشتیم true ریترن می‌کنه و درغیر اینصورت از تابع shouldYieldToHost فایل SchedulerHostConfig.js استفاده می‌کنه و نتیجه اون رو برمیگردونه.پس با استفاده از این تابع می‌تونیم بعد از هر حلقه for چک کنیم که آیا میتونیم بریم سراغ حلقه بعدی، یا باید کنترل رو به scheduler برگردونیم و بقیه کار رو بعدا انجام بدیم.3- continuationاین کانسپت رو تا الان ندیده بودیم. continuationCallback یه تابعیه که قراره ادامه تسکی که درحال حاضر یه بخشیش انجام شده رو انجام بده. نحوه ست کردنش به این شکله که ما می‌تونیم از تابعی که به scheduleCallback دادیم یه تابع ریترن کنیم، و این تابع بعنوان continuationCallback تسک اولیه set میشه. درواقع continuation هم مثل بقیه تسک ها داخل minHeap قرار می‌گیره، ولی expirationTime و همه ویژگی‌هاش، دقیقا برابر همون تسکیه که منجر به ایجاد این continuation شده.توی مثال فیبوناچیمون هم داخل for چک کردیم تا اگه جواب shouldYield برابر true بود، خود تابع work رو ریترن کنیم که ادامه کار تو فرصت دیگه‌ای دنبال بشه.SchedulerHostConfig.jsبالاتر گفتیم که این فایل وظیفه هماهنگ کردن scheduler با پلتفرمی که روش اجرا میشه رو برعهده داره، و یسری فانکشن export می‌کنه مثل requestHostCallback, shouldYieldToHost و getCurrentTime.اما پشت این فانکشن‌ها، کار نسبتا پیچیده‌ای انجام میگیره: تخمین مدت‌زمان هر فریم و مدیریتش.درواقع بخاطر این فایله که توی مثال قبلی انیمیشن ما بدون لگ اجرا میشد، چون SchedulerHostConfig داره تلاش می‌کنه framerate رو روی 60Hz نگه داره. و این‌کار رو از طریق یه حقه خیلی جذاب انجام میده.اگه یادتون باشه بالاتر، تابع scheduleCallback اومد و تابع flushWork خودش رو به یکی از توابع SchedulerHostConfig به اسم requestHostCallback پاس داد. اونموقع فرض کردیم که این تابع صرفا setTimeout می‌کنه با مقدار صفر. حالا، این کد واقعی(ساده‌شده)ی تابع requestHostCallback عه:سورس کد requestHostCallbackاول از همه callback ورودیش(flushWork) رو داخل یه متغیر گلوبال ذخیره می‌کنه، و بعد اگه RAFLoopRunning نباشه، run اش می‌کنه و تابعی رو ست می‌کنه که تنها پارامتر کالبک‌های requestAnimationFrame ینی rAFTime رو به تابع onAnimationFrame میده.میدونیم که تابع requestAnimationFrame یه کالبک ورودی می‌گیره، و اون رو برای هر فریمی که رندر می‌کنه صدا میزنه، شاید حدود ۶۰ بار درثانیه، شاید کم‌تر و شاید بیشتر. درواقع طبق step 11.8 این specification:https://html.spec.whatwg.org/multipage/webappapis.html#step1توابع rAF، آخر هر فریم اجرا میشن و یکی از آخرین api هایین که صدا زده میشن. و تنها آرگومان ورودی تابعی که به rAF پاس داده شده، rAFTime عه، یه DOMHighResTimestamp که تایم‌استمپِ زمانی که مرورگر شروع به صدا زدن animation frame ها کرده رو نمایش میده. اما چرا‌ scheduler اینکارو می‌کنه و چرا نیاز داره آخر هر فریم صدا زده بشه؟برای اینکه خودش رو تطبیق بده. با چی؟ با framerate مرورگر و دستگاه. درواقع تابع onAnimationFrame توی این خط ها، داره با توجه به زمان بین دو rAF متوالی، تخمین میزنه که توی فریم بعدی چقدر زمان برای انجام دادن کار خواهم داشت. اول کارشو با 30fps شروع می‌کنه و بعد با توجه به framerate مرورگر و با استفاده از همین rAF ها، خودش رو با framerate موجود تطبیق میده. همچنین زمان شروع هر frame + طول تخمینی frame رو به اسم frameDeadline ذخیره می‌کنه و بعدا، داخل تابع shouldYieldToHost، چک می‌کنه ببینه آیا از frameDeadline گذشتیم یا نه (در نتیجه انیمیشن اون جعبه قرمز تو مثالمون، خیلی روون اجرا میشد)آخرین کاری که می‌کنه هم استفاده از port.postMessage عه. این چند خط رو ببینید:استفاده از MessageChannel برای زمانبندی تسک ها کلاس MessageChannel یکی از API های مرورگره(داکیومنت) که اجازه میده از نقطه A برای نقطه B پیام بفرستیم (یجورایی شاید بشه گفت Message broker)، اما اینجا این نکته اصلا مهم نیست، چون هردوی نقطه A و B توی همین فایل قرار دارن. چیزی که برای ما مهمه، زمان ارسال پیامه.طبق این specification:https://html.spec.whatwg.org/multipage/web-messaging.html#message-portsهر port یه port message queue داره که یه صف از پیام هاییه که برای این port ارسال شده، و همونطور که داخل specification ذکر کرده، ماهیت واقعی این صف، task source عه. task source ها درواقع متناظرن با task queue ها و دسته‌بندی‌ هایی هستن بر روی task هایی که داخل event loop مون باید انجام شه.اما نکته مهم، یکی از side effect های ارسال پیام از طریق MessageChannelعه. با اینکار، تابع  ای که باری port1 تنظیم شده،‌ اوایل فریم بعدی صدا زده میشه، پس ما میتونیم اوایل فریم، کنترل رو دست بگیریم (راه حل جایگزین استفاده از requestIdleCallback بود، ولی مرورگر ها تو زمینه صدا زدن rIC خیلی تنبلن و خیلی کم‌ صداش می‌زنن)حالا اگه نگاهی به تابع performWorkUntilDeadline بندازیم، (هرچند از اسمش هم معلومه چیکار می‌کنه) میبینیم که scheduledHostCallback ای که داخل requestHostCallback به خاطر سپرده بودیم رو صدا میزنه (درواقع همون flushWork داخل Scheduler.js) و دوتا پارامتر hasTimeRemaining و currentTime رو براش میفرسته. که از اینجا به بعد ماجرا رو هم یاد گرفتیم که چه اتفاقاتی میافته، Scheduler.js شروع می‌کنه به خالی کردن minHeap، و همچنان یه گوشه چشمی هم به تابع  shouldYieldToHost داره که ببینه آیا باید کنترل رو برگردونه یا نه. (درواقع آیا frameDeadline &lt;= currentTime هست یا نه)امیدوارم مقاله مفیدی بوده باشه، اگه تا اینجا دنبال کردید نوشته رو بهتون تبریک میگم، احتمالا شما جزو ۴ درصدی ها هستید :)هر سوال، انتقاد، پیشنهاد، ابهامی بود، خوشحال میشم باهم درارتباط باشیم:@Eddie_CooRo</description>
                <category>Eddie Cooro</category>
                <author>Eddie Cooro</author>
                <pubDate>Fri, 13 Sep 2019 05:58:38 +0430</pubDate>
            </item>
                    <item>
                <title>استفاده از هوک داخل Class Component!! وات؟</title>
                <link>https://virgool.io/iran-react-community/%D8%A7%D8%B3%D8%AA%D9%81%D8%A7%D8%AF%D9%87-%D8%A7%D8%B2-%D9%87%D9%88%DA%A9-%D8%AF%D8%A7%D8%AE%D9%84-class-component-%D9%88%D8%A7%D8%AA-g2oqrszvqzyi</link>
                <description>اینجا واقعا توی یه ClassComponent از useContext استفاده کردیم :)سلام! توی این ویدیو میخوایم برا اولین بار داخل یه Class Component از هوک useContext استفاده کنیم ? پس بریم که باهم یکم توی سورس ری‌اکت بگردیم، ببینیم هوک ها چجوری کار میکنن، و چجوری میشه ری‌اکت رو دور زد و از useContext داخل class component استفاده کرد. (صدالبته که Don&#x27;t try this at home)به گیرنده هاتون دست نزنید.لینک codesandboxلینک Youtube (چون آپارات down بنظر میرسه) https://youtu.be/yfZaJD2n038 دیگر مقالات من: http://vrgl.ir/WWPQ1  http://vrgl.ir/cFW91  http://vrgl.ir/628wV </description>
                <category>Eddie Cooro</category>
                <author>Eddie Cooro</author>
                <pubDate>Fri, 06 Sep 2019 13:37:23 +0430</pubDate>
            </item>
                    <item>
                <title>عجایب optional chaining در js</title>
                <link>https://virgool.io/JavaScript8/%D8%B9%D8%AC%D8%A7%DB%8C%D8%A8-optional-chaining-%D8%AF%D8%B1-js-z9y6ayg2wnny</link>
                <description>1. این optional chaining (در ادامه بهش میگیم oc) یه proposal ایه که حدود یه هفته پیش به استیج ۳ رسیده، و احتمالا توی ES2020 شاهدش باشیم(هرچند الان هم قابل transpile شدنه)2. درکل کارش اینه بهمون کمک کنه به پراپرتی های عمیق یه آبجکت دسترسی داشته باشیم بدون اینکه بدونیم هیچکدوم از prop های بین راه وجود دارن یا نه.مثال:optional chainingتوی اولی اگه address مون undefined باشه ارور میده (undefined is not an object) اما توی دومی اگه address مون undefined باشه streetName برابر undefined میشه.3. اگه یه پراپ داشته باشیم که اسمش رو بخوایم dynamic بنویسیم اینشکلی میشه:optional chaining dynamic prop4. میتونیم ازش برای صدا زدن فانکشن ها هم استفاده کنیم:صدا زدن فانکشن با استفاده از optional chaining
اینجوری حتی اگه fn مون undefined هم باشه ارور نمیخوریم.مثال:5. میشه اینجوری براش default گذاشت:nullish coalescing operatorاسم این عبارت ?? که میبینید nullish coalescing operator هست که خودش یه proposal در استیج 3 عه.فرقش با || اینه که || حتی برای استرینگ خالی و کلا هر falsy value ای هم میره default رو میذاره ولی optional chaining فقط برای null و undefined اینکارو میکنه.6. قبل از این operator جایگزینی که استفاده می‌کردیم عبارت &amp;&amp; بود که خب خیلی مناسب نیست. به دو دلیل:الف) موقع استفاده از &amp;&amp; جاوااسکریپت آخرین عبارت سمت چپ رو برمیگردونه. این یعنی یه همچین چیزی:استفاده از &amp;&amp; بجای optional chainingاما اینجا اگر هم number مون null باشه آخرین عبارتی که بررسی کرده یعنی number رو برمیگردونه و نتیجه برابر null میشه. ولی با optional chaining جواب همیشه undefined عه.ب) موقع استفاده از &amp;&amp; هر falsy value ای منجر به شکسته شدن زنجیره میشه ولی با استفاده از oc فقط و فقط null و undefined حلقه رو میشکنن.استفاده از &amp;&amp; بجای optional chainingتو مثال اول مقدار length میشه 1 چون a یه string خالیه و تبدیل به false میشه و عبارت || اجرا میشه.اما تو مثال دوم مقدار length میشه 0 چون a نه undefined عه و نه null پس پراپرتی length اش خونده میشه و طول a که برابر 0 هست نمایش داده میشه.منابع:https://2ality.com/2019/07/optional-chaining.htmlhttps://github.com/tc39/proposal-optional-chainingدیگر مقالات من: http://vrgl.ir/WWPQ1  http://vrgl.ir/EmGzx  http://vrgl.ir/cFW91 </description>
                <category>Eddie Cooro</category>
                <author>Eddie Cooro</author>
                <pubDate>Wed, 31 Jul 2019 01:57:59 +0430</pubDate>
            </item>
                    <item>
                <title>تیم ری‌اکت دارن چیکار می‌کنن؟ (قسمت هفتم)</title>
                <link>https://virgool.io/iran-react-community/%D8%AA%DB%8C%D9%85-%D8%B1%DB%8C%D8%A7%DA%A9%D8%AA-%D8%AF%D8%A7%D8%B1%D9%86-%DA%86%DB%8C%DA%A9%D8%A7%D8%B1-%D9%85%DB%8C%DA%A9%D9%86%D9%86-%D9%82%D8%B3%D9%85%D8%AA-%D9%87%D9%81%D8%AA%D9%85-e3qv7w2kkgus</link>
                <description>خب. ماجرای این قسمت برمیگرده به بحث Flare.اگه حوصله خوندن ندارید اسکرول کنید پایین تا عبارت سومین PR رو ببینید.و اگه نمی‌دونید Flare چیه یه نگاهی به دقیقه ۵۵ این ویدیو بندازید ( ویدیو از ارائه من در دورهمی جامعه ری‌اکت ایران)با توجه به چیزی که توی این ویدیو گفتم تیم ری‌اکت مشغول تغییر و تحولات بنیادی تو بخش Event System شون هستن که اسم رمز Flare رو بهش دادن. و اونموقع انتظار داشتیم که خروجیی شبیه به این داشته باشه:نحوه استفاده از Flare در ورژن های قدیمیهمونطور که توی دورهمی هم بشدت تاکید کردم که این API ها شدیدا expreimental هستن و هر لحظه ممکنه عوض بشن (حتی با وجود اینکه یه دموی قابل استفاده هم توی دورهمی ران کردیم و کار کردنش رو دیدیم)، الان توی این PR های جدید شاهد زیر و رو شدن API سیستم Flare هستیم.قبل از هرچیز چندساعت قبل اینکه دورهمی ری‌اکت برگزار بشه خود Dominic یه PR رو داد که یه هوک برای Event ها اضافه می‌کرد.(توی ویدیوی بالا راجبش صحبت کردیم) یچیزی شبیه به این:استفاده از hook های جدید Flareو یا حتی:ویژگی propagate در hook های جدید Flareولی متاسفانه تو این PR های جدید شاهد تغییر و تحول این API هستیم.سوال اساسی اینه که چرا؟ مشکل این بود که API قبلی کاری که ری‌اکت میکرد رو واقعا نشون نمی‌داد و باعث میشد مردم فرضیات اشتباهی از قضیه داشته باشن. (یه مشکل کوچیکتر هم این بود که تو معماری بالا برای هر event component یه fiber ساخته میشه. که خب اونقدرا مهم نیست)در واقع بین هر EventComponent و Host node (بخوانید کامپوننت Press و div) باید یک تناظر وجود داشته باشه (نه الزاما یک به یک). به این معنا که هر Event Component در طول زندگی خودش باید باید باید متعلق به یک و فقط یک HostNode باشه. حالا سوال پیش میاد که چی میشه که این قانون نقض میشه؟ مثال زیر رو ببینید:نکته: useToggle و useInterval دوتا customHook هستن که فرض می‌کنیم خودمون جای دیگه پیاده‌شون کردیمتوی این مثال وقتی که Press ساخته میشه کامپوننت div بعنوان اولین فرزندش بهش داده میشه. بعد از یک ثانیه بدون اینکه خود Press رو دوباره بسازیم یا ری‌رندر کنیم کامپوننت فرزندش رو تغییر میدیم و اینبار یه button بجاش میذاریم. اما متاسفانه Press ما همچنان به همون div اولیه وصل شده و API هم خیلی راحت بهمون اجازه میده همچین bug هایی بوجود بیاریم.از طرفی هم کامپوننتی مثل FocusScope میتونه چندتا فرزند بگیره اما Focus فقط یک فرزند میپذیره و این  عدم یک‌دستی در API رو بوجود میاره.حالا تیم ری‌اکت شروع کردن که تو این حالت ها بهمون warning نشون بدن. ولی پیدا کردن و نمایش دادن این warning ها نسبتا مشکل بود. (این if ساده ترین حالت ممکنه. مثلا حالتی رو فرض کنید که کامپوننت فرزند Suspense شده)برای همین (و یسری مورد دیگه) تیم به فکر API جایگزین افتادن.تو این مقاله سه تا PR مختلف رو به ترتیب بررسی می‌کنیم که ببینیم چه تغییر و تحولاتی رخ داده.اولین PR:اول Dominic طی این PR یه شکل جایگزین رو بررسی کرد. با این سیستم جدید کدهامون اینشکلی میشن:استفاده از ref در API جدیدتوی این راه‌حل جایگزین EventResponder ها مستقیما به ref وصل می‌شن. اینجوری دیگه مشکلاتی که بالاتر ذکر کردیم بوجود نمیاد. هر Responder به یک ref وصل میشه و اگر تغییری اتفاق بیافته pressResponder هم بی‌اطلاع نمی‌مونه.اما این PR هیچوقت مرج نشد و همونطور که Dominic گفت طی بحث های داخلی به یک API جایگزین رسیدن که میشه موضوع PR بعدی.دومین PR:این PR نتیجه صحبت های داخلی تیم بود. از اونجایی که خیلی وقتا استفاده از ref می‌تونه منجر به باگ بشه(برای ما نه، وقتی که برای ری‌اکت کد میزنیم منظورمه) طی این PR اومدن event listener ها رو بجای اولین host node فرزند، به اولین host node پدر چسبوندن و بیخیال ref ها شدن.بشخصه خیلی خوشحالم که API نهایی این نبود (قطعا متخصصین امر API نویسی تو تیم نمیذارن این به production برسه و صرفا یه آزمایش کوچولو بود که مام نباید خیلی باخبر میشدیم :دی) اما درنهایت یه همچین چیزی به دست ما میرسه:هر EventResponder بجای اولین host node فرزند به اولین host node پدر میچسبهتوی این طراحی جدید دیگه (خوشبختانه) نیازی به ref نداریم. و ازونجایی که children یکی از prop های کامپوننت div محسوب میشه مشکلی با حالت های conditional نخواهیم داشت. و حتی اگه کاربر با کلی زحمت موفق بشه همچین باگی ایجاد کنه ری‌اکت خیلی راحت متوجه میشه و warning نشون میده.درباره این PR کلی بحث شکل گرفت و واضحا خودشون هم از این API رو به بالا راضی نیستن. ولی خب بهترین گزینه در لحظه بوده که ارزش چک کردن داشته.سباستین خیلی از این سیستم جدید خوشش میاد و معتقده خیلی خوب با معماری ری‌اکت هماهنگه و مناسبه کارشون هست. توی این کامنت یسری دلیل رو ذکر می‌کنه اما مهمترینشون اینه که ری‌اکت (و همه فریم‌ورک های فرانت‌اند) خیلی روی component هاش مانور میده. توی سیستم قبلی خیلی راحت بود که از بیرون کامپوننت بتونیم کامپوننت داخلی رو خراب کنیم. یا مجبور باشیم از ساختار کامپوننت داخلی اطلاع داشته باشیم تا بتونیم از EventComponent ها استفاده کنیم (همون مثال کامپوننت های A, B که بالاتر زدم.)اما سیستم جدید اینطور نیست. سباستین معتقده که مشکل مشابهی هم با ref ها داشتن. بعنوان مثال اول میخواستن خودکار forwardRef هارو بچسبونن به بیرونی‌ترین hostNode یه کامپوننت فرزند. یعنی بعنوان مثال اگه همچین چیزی داشته باشیم:مشکلات auto forward refسیستم forwardRef اتوماتیک برای MyCustomInput1 خیلی خوب کار می‌کنه ولی اگه یه div (مثلا برای استایل دهی) به دور input مون اضافه کنیم (مثل MyCustomInput2) دیگه forwardRef از کار میافته. و ایرادهایی از این جنس بود که باعث شد کاری کنن فانکشن forwardRef قدرت بیشتری بهمون بده.حالا همین مشکل ها هم برای API قبلی صادق بود. بعنوان مثال شاید بیرونی ترین host node یه کامپوننت مناسب ترین جا برای چسبوندن event listener ای از جنس Hover نباشه.اما با همه این تفاسیر سباستین معتقده که این API یکم گنگ و نامفهومه و یسری موضوع پیشنهاد میده برای بهتر کردنش:۱- یه کوچولو تر و تمیز کردنش یا بهبود های ریز syntax ای. یچی تو مایه های این مثلا:تبدیل component ها به functionکه خب واقعا زحمت کشید با این پیشنهادش :) خسته شد.۲- بیان این کانسپت listener هایی که دارن رو وااااااااااااااقعا بعنوان یه هویت جدید درنظر بگیرن و بصورت first class ازش پشتیبانی کنن. حتی توی خود jsx. پیشنهادش اینه که میتونیم یه کانسپت جدیدی توی jsx معرفی کنیم به عنوان decorator برای تگ ها. که این Responder ها یه مدل decorator باشن۳- بجای اینکه خود کد رو First class کنن بیان کانسپت رو first class کنن. میگه که اگه چیزهای دیگه‌ای هم پیدا کنیم که API شبیه به این داشته باشن میتونیم همرو باهم معرفی کنیم و یاد دادنش کلی راحت تر میشه. با تغییر دادن نحوه تفکر مردم و دیدشون نسبت به jsx میتونن راحت تر با این API کنار بیان. میگه که اگه بهش به شکل چیزی که داخل dom رندر میشه نگاه کنی، خیلی عجیب و دور از ذهنه که چجوری میتونه روی parent خودش listener بذاره، ولی اگه بهش به چشم یه ابزار طراحی visual نگاه کنی کار راحت تر میشه. مثل ابزار fill توی paint که وقتی توی شکل کلیک می‌کنی پدرش رو پر می‌کنه، این هم یچیز تو این مایه‌هاسبگذریم. درنهایت هرچی که بود این هم مرج نشد و رفتیم سراغ API آخر.سومین PR:اینیکی دیگه مرج شده :)این PR دیزاینی رو معرفی می‌کنه که هم مشکلات رو حل می‌کنه هم API تمیزتری نسبت به PR دوم داره.سیستم جدید از دو بخش کلیدی تشکیل میشه، Responder ها و Listener ها.طبق این API جدید دیگه بجای اینکه Responder هارو بعنوان بچه های کامپوننت بدیم، باید بعنوان prop پاس داده بشن. چیزی شبیه به این:آخرین API پیشنهاد شده برای Flare بنظر من که nice میاد ?هر host node (بخونید div) میتونه هرچندتا که دلش خواست responder ورودی بگیره و وقتی گرفت یه اتصال بین responder ها و این div رخ میده که کاملا واضحه. دیگه ممکن نیست مشکل conditional ندانسته بوجود بیاد.و functional component ها می‌تونن به این شکل Listener بشن:نحوه تعریف listenerهروقت event ای روی هرکدوم از EventResponder ها رخ بده، شروع به propagate کردن در درخت ری‌اکت می‌کنه تا زمانی که به اولین listener برسه. اونجا listener اون event رو هندل می‌کنه و متوقف میشه.اگر هم چندتا Responder کنار همدیگه داشته باشیم، Listener به همشون گوش می‌کنه:چند div با PressResponderتو این مثال PressListener داخل App هم به Press های Div A گوش میده هم Div B.در نهایت برای مثالی که اول مقاله داشتیم، توی سیستم جدید به اینشکل در‌اومده.قبل عمل:بعد عمل:والسلام :)شب خوش. http://vrgl.ir/plcbz دیگر مقالات من: https://virgool.io/iran-react-community/%DA%A9%D8%A7%D8%B1%D9%87%D8%A7%DB%8C-%D8%AA%DA%A9%D8%B1%D8%A7%D8%B1%DB%8C-%D9%85%D9%85%D9%86%D9%88%D8%B9-%D9%82%D8%B3%D9%85%D8%AA-%DB%B1-numfwzclbnqj  https://virgool.io/JavaScript8/%D9%81%D8%A7%D9%86%DA%A9%D8%B4%D9%86%D8%A7%D9%84-js-%D8%A8%D8%AF%D9%88%D9%86-%D8%AF%D8%B1%D8%AF-%D9%88-%D8%AE%D9%88%D9%86%D8%B1%DB%8C%D8%B2%DB%8C-%D8%A8%D8%AE%D8%B4-%DB%8C%DA%A9-reduce-tghl6fzl5r8u  https://virgool.io/iran-react-community/how-to-paginate-in-reactredux-like-a-hero-y0puyffsdj6v </description>
                <category>Eddie Cooro</category>
                <author>Eddie Cooro</author>
                <pubDate>Wed, 24 Jul 2019 06:31:26 +0430</pubDate>
            </item>
                    <item>
                <title>تیم ری‌اکت دارن چیکار می‌کنن؟ (قسمت ششم)</title>
                <link>https://virgool.io/iran-react-community/%D8%AA%DB%8C%D9%85-%D8%B1%DB%8C%D8%A7%DA%A9%D8%AA-%D8%AF%D8%A7%D8%B1%D9%86-%DA%86%DB%8C%DA%A9%D8%A7%D8%B1-%D9%85%DB%8C%DA%A9%D9%86%D9%86-%D9%82%D8%B3%D9%85%D8%AA-%D8%B4%D8%B4%D9%85-ry84048rb6de</link>
                <description>بعد از مدت‌ها یسری PR جذاب روی React دیدم که یکیشون رو برای این مقاله انتخاب کردم.این PR هم روی کامپوننت SuspenseList کار می‌کنه.اگه نمی‌دونید SuspenseList چیه مقاله های‌زیر رو بخونید: (مخصوصا دومی رو چون باهاش کار داریم) http://vrgl.ir/cFW91  http://vrgl.ir/ixPrR  http://vrgl.ir/xqSoR قبل از هرچیز یه نکته‌ای رو بگم که اطلاعاتم راجب این کامیت کامل نیست و دارم برداشت خودم از نوشته های سباستین +‌ تغییرات PR رو می‌نویسم.خب حالا تو این کامیت جدید چی به SuspenseList اضافه شده؟من‌بعد یه پراپ جدید داریم به اسم tailMode که با توجه به این خط ها فقط با revealOrder های forwards و backwards کار می‌کنه.استفاده از tailMode در کنار revealOrderاگه یادتون باشه راجب forwards گفتیم حتی اگه دیتای یه کامپوننت حاضر باشه منتظر کامپوننت های قبل خودش میمونه تا Suspense شون به اتمام برسه بعد نمایش داده بشه. حالا اگه ۴ تا کامپوننت داشته باشیم به اسم های A, B, C و کامپوننت A مون resolve شده باشه، چه بلایی سر کامپوننت های B و C میاد؟ تو حالت عادی جفتشون fallback خودشون رو نشون میدن. و پراپ جدید tailMode برای کنترل کردن این fallback ها یا اصطلاحا tail ‌‌کامپوننت SuspenseList اومده.اگه tailMode رو برابر collapsed قرار بدیم این fallback ها collapse میشن و فقط اولیشون نمایش داده میشه. یعنی اگه سه‌تا کامپوننت A, B, C داشته باشیم و اولی resolve شده باشه, فقط کامپوننت B مون fallback نشون میده و کامپوننت C هیچ چیزی نمایش نمیده.باید تاکید کنم که این prop فقط روی &quot;نمایش داده شدن&quot; کامپوننت ها اثر میذاره و کاری با پردازش شدن یا نشدنشون نداره. یعنی در همین حین که کامپوننت C هیچ fallback ای نمایش نمیده اما تو پشت صحنه مشغول fetch کردن دیتاش/انجام دادن کارش هست.راجب کاربردش, چیزی که فعلا به ذهن من میرسه صفحه فیده. فرض کنید یسری پست داریم که revealOrder شون روی forwards هست و یکی یکی باید نمایش داده بشن و fallback شون هم spinner عه. حالا اگه tailMode رو نداشته باشیم یه عالمه اسپینر میبینم ولی باوجود tailMode میتونیم جوری کامپوننت SuspenseList ری‌اکت رو تنظیم کنیم که فقط اولین Spinner رو نشون بده و بقیشون نمایش داده نشن. صد البته که چیزی که خود سباستین از کاربردهاشون میدونه خیلی گسترده تره، یه صحبت‌هایی هم راجب sssr کرده که چون هنوز نه مقاله‌ای راجب Fizz نوشتم و نه کاری برای مقدارهای دیگه‌ای که tailMode میتونه بپذیره انجام شده, فعلا بازش نمی‌کنم.https://github.com/facebook/react/pull/16007 http://vrgl.ir/8cYu5  http://vrgl.ir/9XOkz دیگر مقالات من: http://vrgl.ir/EmGzx  http://vrgl.ir/628wV  http://vrgl.ir/7Xs2l </description>
                <category>Eddie Cooro</category>
                <author>Eddie Cooro</author>
                <pubDate>Sat, 20 Jul 2019 23:39:49 +0430</pubDate>
            </item>
                    <item>
                <title>تیم ری‌اکت دارن چیکار می‌کنن؟ (قسمت پنجم)</title>
                <link>https://virgool.io/iran-react-community/%D8%AA%DB%8C%D9%85-%D8%B1%DB%8C%D8%A7%DA%A9%D8%AA-%D8%AF%D8%A7%D8%B1%D9%86-%DA%86%DB%8C%DA%A9%D8%A7%D8%B1-%D9%85%DB%8C%DA%A9%D9%86%D9%86-%D9%82%D8%B3%D9%85%D8%AA-%D9%BE%D9%86%D8%AC%D9%85-aoel13z6xunx</link>
                <description>سلام. امروز می‌خوام راجب یکی از micro optimization هایی که روی ری‌اکت اتفاق افتاد بگم :)البته چیز خیلی گفتنیی نیست ولی دوست داشتم راجبش حرف بزنم که هم ببینید چقدر ریز به بحث performance نگاه می‌شه هم ببینید تازه وارد ها چجوری به سورس ری‌اکت کانتریبیوت می‌کنن و چقدر کامیت هاشون ریزه.خب این اسم کامیت هست Slightly improve performance of hydration. همونطور که از اسم کامیت هم معلومه, تغییراتی که اتفاق افتادن قراره یه کوچولو پرفورمنس hydration رو بهتر کنن.برا دیدن تغییرات می‌تونید به اینجا برید یا عکس زیر رو ببینید:خب همونطور که توی تغییرات مشخصه اولین اتفاقی که افتاده اینه که تابع getNextHydrateSibling کوچیک‌تر شده و یه تابع دیگه به اسم getNextHydrate ساخته شده که بخش اعظم کد به داخل این تابع منتقل شده. دلیلش هم این هست که کد بتونه داخل هردوی getNextHydrateSibling و getFirstHydrateChild استفاده بشه. بعد اینکه یه نگاهی به نحوه فراخوانی getNextHydrate بندازید متوجه میشیم که این تابع چقدر کد رو تمیزتر کرده و چقدر منطقی تره بودنش, پس تا همینجا شانس خیلی زیادی داریم که این کامیت روی مستر بره و منتشر بشه :).حالا یه نگاه به بدنه getNextHydrate بندازیم. وظیفه این تابع اینه که بین داداشای node ای که ورودی می‌گیره بگرده و اولین برادری که میشه hydrate اش کرد رو برگردونه. با توجه به کد node های زیر قابل hydrate ان:۱- ELEMENT_NODE و TEXT_NODE که همون المنت ها و تکست های خودمونن.اگر suspense روی سرور روشن باشه:۲- COMMENT_NODE۳- SUSPENSE_START_DATE۴- SUSPENSE_FALLBACK_START_DATE۵- SUSPENSE_PENDING_START_DATEو اگر node ما هر type ای غیر از این‌ها داشته باشه, break اتفاق نمی‌افته و اگر به حلقه for نگاه کنیم هر مرحله node = node.nextSibling قرار می‌گیره.بنظرم کد مینیمال و جذابی میاد, یه نمونه موفق از خیلی مینیمال ریفاکتور کردنه.اما پرفورمنسش کجا بود؟؟؟ الان بهتون میگم :)اگه به کد قدیمی نگاه کنید اینجا که data داره چک میشن, این اتفاق مستقیم توی تک تک شرط‌های while افتاده. پس توی یک بار اجرای حلقه while, ما سه بار node.data رو اینجا و اینجا و اینجا صدا زدیم که بهرحال هرچقدر کم ولی یکم downside پرفورمنسی داره. اما توی کد جدید تو این خط nodeData گرفته شده و داخل if زیرش سه بار از رفرنسی که داریم برای چک کردن استفاده شده.نکته‌ای که باید بهش تاکید کنم اینه که تو کد خودتون حتی ۱ درصد هم نیاز نیست به فکر این مدل optimization ها باشید. ری‌اکت یه کتابخونه خیلی خیلی معروفه که هرکدوم از این فانکشن هاش چند میلیارد بار در روز شاید صدا زده بشن. پس حتی یه کندی 0.1ms ای ‌میتونه قطره قطره جمع بشه و در نهایت تبدیل بشه به چند‌ ده ساعت در روز. پس منطقیه که بیشتر از ما به فکر باشن.و در آخر توجه شمارو به این کامنت از سباستین جلب می‌کنم:We’re moving to a selective hydration approach driven by interaction which effectively makes the paths lazy but also able to warm up in preparation for an interaction. So the characteristics are about to change.https://github.com/facebook/react/pull/15998 http://vrgl.ir/JtWya  http://vrgl.ir/plcbz دیگر مقالات من: http://vrgl.ir/EmGzx  http://vrgl.ir/628wV  http://vrgl.ir/7Xs2l </description>
                <category>Eddie Cooro</category>
                <author>Eddie Cooro</author>
                <pubDate>Sat, 29 Jun 2019 15:19:52 +0430</pubDate>
            </item>
                    <item>
                <title>تیم ری‌اکت دارن چیکار میکنن؟ (قسمت چهارم)</title>
                <link>https://virgool.io/iran-react-community/%D8%AA%DB%8C%D9%85-%D8%B1%DB%8C%D8%A7%DA%A9%D8%AA-%D8%AF%D8%A7%D8%B1%D9%86-%DA%86%DB%8C%DA%A9%D8%A7%D8%B1-%D9%85%DB%8C%DA%A9%D9%86%D9%86-%D9%82%D8%B3%D9%85%D8%AA-%DA%86%D9%87%D8%A7%D8%B1%D9%85-okx7juxpbkh0</link>
                <description>این کامیت یکم جذاب تر از کامیتای قبلیه, از این لحاظ که به API ربط نداره و مربوط به لایه هایی پایین تر ری‌اکته (خیلی پایینتر, تقریبا دور و بر خود Scheduler). ما هم حین بررسی کردنش سعی می‌کنیم یکم رویکردمون رو عوض کنیم و بیشتر کدهای ری‌اکت رو ورق بزنیم :)خب, همه چی از اونجا شروع شد که بچه های فیسبوک تصمیم گرفتن اولین کانتریبیوتشون رو به W3C انجام بدن و یه api جدید معرفی کنن و توی WICG منتشرش کنن به اسم isInputPending که میتونید specification اش رو از اینجا بخونید. این api به ما اجازه میده که بفهمیم آیا کاربر درحال تعامل با صفحه وب هست یا نه. طرز استفاده اش هم به این شکله:navigator.scheduling.isInputPending(arrayOfInputEventTypes)که بعنوان آرگومان ورودی یه آرایه از eventType های مختلف رو میگیره و به ما میگه که آیا هیچکدوم از این event ها بدلیل بلاک شدن ترد توسط کد ما متوقف شدن یا نه. اگر هیچ آرگومانی هم ورودی ندیم همین کار رو برای همه eventType هایی که پشتیبانی می‌کنه انجام میده. راجب eventType های پشتیبانی شده اینجا گفتن که باید هر سه ایونت click, keydown و wheel ساپورت بشن و سایر ایونت ها مثل MediaCapture به عهده مرورگر هست که آیا پشتیبانی بکنه یا نه. (دقت کنید داریم راجب api خوده خود مرورگر ها صحبت می‌کنیم که ارتباطی با کار ری‌اکت نداره و الان تو ورژن ۷۵ کروم هم می‌تونید بصورت experimental استفاده کنید این api رو)تو ویدیوی کوتاه زیر نحوه کار این api رو کامل ‌می‌بینید. من که به شخصه خیلی دوستش دارم :)   https://www.aparat.com/v/lj4co (اگه مرورگر کرومتون ورژنش بین ۷۴ و ۷۶ عه می‌تونید دموی بالا رو از اینجا امتحان کنید. سورسش هم اینجا موجوده.)خب حالا این چه ربطی به ری‌اکت داره؟داخل ارائه‌ام توی سومین دورهمی جامعه ری‌اکت ایران مفصل راجب fiber و پکیج scheduler و اینکه چجوری روی پرفورمنس اپ ما تاثیر میذارن صحبت کردم (لینک). و گفتیم ری‌اکت برای اینکه صفحه رو ریسپانسیو نگه داره مرتب کنترل رو به دست مرورگر برمیگردونه تا مرورگر کارهای خودش رو انجام بده, حتی اگه درواقع کاری وجود نداشته باشه حدود ۶۰ بار در ثانیه ری‌اکت رندر کردن خودش رو متوقف می‌کنه که باعث میشه یه کوچولو روی سرعت رندر کردنش تاثیر منفی بذاره. حالا به لطف این api, پکیج scheduler کم‌تر مزاحم ری‌اکت میشه و میتونه فقط مواقعی که کاربر تعاملی با صفحه داشته درخواست کنترل کنه.ولی همچنان همونطور که تو این کامیت می‌بینیم ری‌اکت هر ۳۰۰ میلی‌ثانیه فارغ از اینکه چه اتفاقی افتاده یدور کنترل رو دست مرورگر برمیگردونه.عمده تغییرات توی این فایل و داخل فانکشن shouldYieldToHost اتفاق افتاده‌ان. توی این خط چک کردیم که اگه هنوز از ۱۶ میلی‌ثانیه نگذشتیم (۶۰ بار در ثانیه) به کارمون ادامه بدیم و توجهی به هیچی نداشته باشیم. توی این خط چک شده که آیا isInputPending هست یا نه که اگه باشه وارد شرط نمی‌شیم و مستقیم true برمیگردونیم تا YieldToHost اتفاق بیافته و مرورگر کنترل رو دست بگیره. اما اگه نداره داخل بدنه شرط این عبارت رو برمیگردونیم که درواقع اگه ۳۰۰ میلی‌ثانیه از پایان زمان ۱۶ میلی‌ثانیه‌ای ما گذشته باشه true عه و کنترل به دست مرورگر برمگیرده و اگر نه همچنان false عه و کنترل دست ری‌اکت می‌مونه.https://github.com/facebook/react/pull/15959 http://vrgl.ir/xqSoR  http://vrgl.ir/8cYu5 دیگر مقالات من: http://vrgl.ir/628wV  http://vrgl.ir/EmGzx  https://virgool.io/@eddiecooro/aoel13z6xunxhttp://vrgl.ir/7Xs2l </description>
                <category>Eddie Cooro</category>
                <author>Eddie Cooro</author>
                <pubDate>Thu, 27 Jun 2019 22:17:19 +0430</pubDate>
            </item>
                    <item>
                <title>کارهای تکراری, ممنوع! (قسمت دوم)</title>
                <link>https://virgool.io/iran-react-community/%DA%A9%D8%A7%D8%B1%D9%87%D8%A7%DB%8C-%D8%AA%DA%A9%D8%B1%D8%A7%D8%B1%DB%8C-%D9%85%D9%85%D9%86%D9%88%D8%B9-%D9%82%D8%B3%D9%85%D8%AA-%D8%AF%D9%88%D9%85-fvbdbbqoavhw</link>
                <description>تو قسمت اول کارهای تکراری ممنوع, راجب vim صحبت کردیم و قابلیتی به اسم macro که به ما اجازه میده خیلی از کارهای تکراریی که ممکنه هرروز انجام بدیم رو ساده سازی کنیم.اما اگه کارها کمی پیچیده تر بشن چی؟مثال زیر رو درنظر بگیرید:اپلیکیشن ری‌اکت نیتیوی داریم که در بعضی از کامپوننت هاش کدی شبیه مثال زیر داریم:کامپوننت MyComponent یک عکس قلب نمایش می‌دهدتو مثال بالا می‌بینیم که یه آبجکت جاوا‌اسکریپتی ایمپورت شده و اسمش رو base_images گذاشتیم. چند خط پایین تر فیلد heart این آبجکت بعنوان uri فیلد src به کامپوننت Image داده شده.میخوایم خروجی زیر رو داشته باشیم:حالا کامپوننت MyComponent از inline require برای ایمپورت کردن عکس استفاده میکندخب برای اینکه از عکس بالا به این خروجی برسیم باید قدم‌های زیر رو طی کنیم:۱- ایمپورت رو کلا حذف کنیم.۲- آبجکت جاوااسکریپتیی که یکی از فیلد های آبجکت ایمپورت شده بعنوان فیلد uri توش استفاده شده رو پیدا کنیم.۳- آبجکت رو حذف کنیم.۴- عبارت require رو بنویسیم۵- آدرس ایمپورتی که حذف کردیم رو داخل require بنویسیم۶- عبارت /encodedAssets رو از داخل آدرس حذف کنیم۷- عبارت بعد از آخرین / رو از توی آدرس حذف کنیم۸- اسم فیلدی از آبجکت ایمپورت شده که قبلا بعنوان uri استفاده کرده بودیم رو پیدا کنیم (تو این مثال heart)۹- اسمی که تو مورد ۸ پیدا کردیم رو به آخر آدرس بچسبونیم و بعد از اون یه .png بذاریملیست طولانیی شد. فقط این موضوع رو اضافه کنید که این مراحل نه یک‌بار, بلکه به ازای تک تک فایل های پروژه که داخلشون چیزی از encodedAssets ایمپورت شده باید انجام بشن :)اولین تلاش من برای حل کردن مسئله بالا روش دستی بود; که خیلی سریع وقتی فهمیدم حدود ۸۰ تا فایل رو باید ادیت کنم با شکست مواجه شد.روش دوم replace کردن عه. اینکه ما یه regex ای بنویسیم که عبارت های بالا رو پیدا کنه و replace اشون کنه. که خب ممکن بود کار کنه ولی یه بزرگی گفته &quot;هروقت برای حل مشکلی از regex استفاده کردید, ازون ببعد دوتا مشکل خواهید داشت&quot;. مخصوصا که regex نسبتا پیچیده ای نیازه که بتونه آبجکت جاوا اسکریپتی که ایمپورت توش استفاده شده رو پیدا کنه. و replace های عجیبی هم احتمالا باید انجام بدیم. درکل نه تخصصش رو داشتم نه حال سر و کله زدن با regex رو :)رویکرد بعدی هم منطقا macro های vim ان که خب واضحا اینجا کمکی بهمون نمیکنن. ما چیزی می‌خوایم که ساختار جاوااسکریپت مارو بفهمه و بتونه متوجه بشه آبجکت چیه, آدرس ایمپورت چیه,  فیلد ینی چی و چیزهایی از این قبیل. پس حتی این راه حل هم شکست خورده محسوب میشه.پس می‌رسیم به آخرین خط دفاعیمون. codemod های عزیز دل. ابزار های تغییر کدی که صرفا replace نمی‌کنن, قبلش کدت رو میخونن, می‌فهمن و AST اش رو میسازن.درحال حاضر پرکاربرد ترین ابزار برای این‌کار کتابخونه jscodeshift هست که خودش از چند بخش تشکیل شده:بخش اول; یه transpiler واقعی جاوااسکریپته که کد جاوااسکریپت ما رو میخونه و AST اون رو میسازهبخش دوم; یسری ابزارن برای traverse کردن این AST ساخته شده و پیدا کردن و تغییر دادن قسمت هایی که لازمه تغییر کننبخش سوم; ابزاری برای تبدیل دوباره AST به کد javascript ضمن حفظ code-style ما (مثلا اگه تو کد ارجینال از دوتا space استفاده کرده باشم و طول خط هام بیشتر از ۸۰ کاراکتر نباشه, این موارد توی کد خروجی هم لحاظ می‌شن)تو این ویدیو سعی کردم با استفاده از codemod رو مثالی که زدم کار کنم و ببینیم که بالاخره چجوری موفق شدم این بار هم از انجام دادن کارهای تکراری فرار کنم.پس... کارهای تکراری, ممنوع!!!لینک آپارات: لینک http://aparat.com/v/2eQlf  http://vrgl.ir/EmGzx دیگر مقالات من: http://vrgl.ir/cFW91  http://vrgl.ir/628wV  http://vrgl.ir/7Xs2l </description>
                <category>Eddie Cooro</category>
                <author>Eddie Cooro</author>
                <pubDate>Wed, 26 Jun 2019 23:43:27 +0430</pubDate>
            </item>
                    <item>
                <title>تیم ری‌اکت دارن چیکار میکنن؟ (قسمت سوم)</title>
                <link>https://virgool.io/iran-react-community/%D8%AA%DB%8C%D9%85-%D8%B1%DB%8C%D8%A7%DA%A9%D8%AA-%D8%AF%D8%A7%D8%B1%D9%86-%DA%86%DB%8C%DA%A9%D8%A7%D8%B1-%D9%85%DB%8C%DA%A9%D9%86%D9%86-%D9%82%D8%B3%D9%85%D8%AA-%D8%B3%D9%88%D9%85-yfj9yuog46ay</link>
                <description>خب کامیت امروز هم در راستای همون فیچر Suspense و SuspenseList عه. چون آخر هفته اس یکم حجم کامیت ها کم شده و همه تو تعطیلات به‌سر میبرن, ولی دیروز سباستین یه کامیت کرد که نظرمو جلب کرد.این اسم PR ایه که باز کرده‌: Expire rendering the tail of SuspenseList after a timeoutقضیه چیه؟ اینجوری که خود سباستین توضیح میده بعضی وقتا هست که ما کل لیستمون رو لود کردیم, ینی دیتای همه کامپوننت ها حاضرن اما هر کامپوننت واسه رندر شدن مقدار زیادی CPU مصرف میکنه. در این صورت اگه فرض کنیم ۱۰۰ تا کامپوننت توی لیستمون هستن و هرکدوم ۱۰۰ میلی ثانیه طول میکشن برای رندر شدن, حتی با وجود اینکه دیتای همشون لود شده اما باز ۱۰۰۰۰ میلی ثانیه یعنی ۱۰ ثانیه طول میکشه تا همه آیتم ها رندر بشن و بشه دیدشون. درواقع مشکل اینجاس که کامپوننت های اول لیست و آخر لیست باهم باید نمایش داده بشن (together).اما وقتی کامپوننت های پایینتر بدلیل رندر کندشون دارن مانع کامپوننت های بالایی میشن, این کامیت این اجازرو به ری‌اکت میده که اگر رندر شدن لیست از یه تایم مشخصی (درحال حاضر ۵۰۰ میلی ثانیه) بیشتر طول کشید, هرچیزی که تا الان رندر کرده رو نمایش بده و برای بقیه placeholder رو mount کنه و توی دفعه بعدی بقیه لیست رو رندر کنه.آپدیت:برخی ایراد گرفتن که وقتی کسی revealOrder رو برابر با together گذاشته یعنی میخواد که همشون باهم نمایش داده بشن, و تحت هیچ شرایطی نباید اینجوری وقفه بینشون بیافته. من هم تا حد زیادی موافقم و برای جزییات موضوع باید منتظر بمونیم تا اگر SuspenseList به api ری‌اکت راه پیدا کرد, توی داکیومنتش چی می‌نویسن.ولی چیزی که من تا الان متوجه شدم اینه که فرض کنید revealOrder ما forwards باشه و کامپوننت اول هم درحال نمایش داده شدنه. حالا اگه کامپوننت های ۲ تا ۹ بصورت همزمان دیتاشون حاضر بشه, ری‌اکت با این‌ها بصورت together رفتار میکنه چون همشون میتونن نمایش داده بشن.حالا سنگین بودن رندر رو به قضیه اضافه کنیم می‌بینیم که کامپوننت ۲ تا ۵ رندرشون تموم می‌شه, نمایش داده می‌شن و کامپوننت‌های ۶ ببعد یکم بیشتر loading نشون میدن تا سری بعدی که فرصت رندر شدن پیدا کنن.https://github.com/facebook/react/pull/15946 http://vrgl.ir/ixPrR  http://vrgl.ir/JtWya دیگر مقالات من: http://vrgl.ir/628wV  http://vrgl.ir/7Xs2l  http://vrgl.ir/EmGzx </description>
                <category>Eddie Cooro</category>
                <author>Eddie Cooro</author>
                <pubDate>Sun, 23 Jun 2019 16:08:51 +0430</pubDate>
            </item>
                    <item>
                <title>تیم ری‌اکت دارن چیکار میکنن؟ (قسمت دوم)</title>
                <link>https://virgool.io/iran-react-community/%D8%AA%DB%8C%D9%85-%D8%B1%DB%8C%D8%A7%DA%A9%D8%AA-%D8%AF%D8%A7%D8%B1%D9%86-%DA%86%DB%8C%DA%A9%D8%A7%D8%B1-%D9%85%DB%8C%DA%A9%D9%86%D9%86-%D9%82%D8%B3%D9%85%D8%AA-%D8%AF%D9%88%D9%85-jruvmue9tcj1</link>
                <description>خب کم‌کم داریم میرسیم به کامیت جذابی که دیروز گفتم دیدم :)این کامیت مرتبط با همون بحث SuspenseList عه و برای همین ناچارم اول راجب pull request خود SuspenseList مفصل حرف بزنم تا بعد برسیم به کامیت موعود.خب سباستین دیشب ساعت دهونیم شب به وقت ایران یه مرج‌ریکوئستی زد که گزینه های forwards و backwards رو به گزینه های موجود برای revealOrder اضافه کرد.فکر می‌کنم از اسمش مشخص باشه که چیکار قراره بکنه. بعنوان مثال نمونه کد زیر رو ببینید:گزینه forwards برای پراپ revealOrder کامپوننت SuspenseListخب اگه فرض کنیم اول از همه کار کامپوننت ThirdSuspendingComponent تموم میشه, با توجه به revealOrder که برابر forwards هست, همه کامپوننت ها همچنان Loading رو نمایش میدن.حالا اگه FirstSuspendingComponent کارش رو تموم کنه منتظر چیزی نمیمونه و بلافاصله محتواش رو نشون میده, ولی ThirdSuspendingComponent همچنان منتظر SecondSuspendingComponent می‌مونه و به محض تموم شدن کار Second دوتایی باهم محتواشون رو رندر میکنن.گزینه backwards هم دقیقا برعکس این موضوع رو انجام میده. یعنی هر آیتم برای نمایش داده شدن باید منتظر آیتم های بعد از خودش بمونه.برای اینکه دقیقا با نحوه کار این مقادیر آشنا بشید حتما دموی زیر رو ببینید (نکته:‌چندبار صفحه رو رفرش کنید تا تفاوت هارو بهتر متوجه بشید)دموhttps://github.com/facebook/react/pull/15918 http://vrgl.ir/cFW91  http://vrgl.ir/xqSoR دیگر مقالات من: http://vrgl.ir/628wV  http://vrgl.ir/7Xs2l  http://vrgl.ir/EmGzx </description>
                <category>Eddie Cooro</category>
                <author>Eddie Cooro</author>
                <pubDate>Sat, 22 Jun 2019 09:53:15 +0430</pubDate>
            </item>
                    <item>
                <title>تیم ری‌اکت دارن چیکار میکنن؟ (قسمت اول)</title>
                <link>https://virgool.io/iran-react-community/%D8%AA%DB%8C%D9%85-%D8%B1%DB%8C%D8%A7%DA%A9%D8%AA-%D8%AF%D8%A7%D8%B1%D9%86-%DA%86%DB%8C%DA%A9%D8%A7%D8%B1-%D9%85%DB%8C%DA%A9%D9%86%D9%86-%D9%82%D8%B3%D9%85%D8%AA-%D8%A7%D9%88%D9%84-pkmkse0asd3w</link>
                <description>امروز لابه‌لای کامیت های هسته ری‌اکت یه کامیت جالب دیدم.حدود ۴ روزه که sebastian markbage داره روی چیزی کار میکنه به اسم SuspenseList.این کامپوننت گویا قراره کار هدایت و هماهنگ سازی چندتا Suspense رو انجام بده, توی چندتا کامیت اول بخش ابتدایی عملکردش کامل شده, که یه همچین API ای بهمون میده:کامپوننت جدید SuspenseListتو این مثال فرض کنید دوتا کامپوننت FirstSuspendingComponent و SecondSuspendingComponent به محض mount شدن یه promise رو throw میکنن و نیاز دارن که suspend شن. پس روی صفحه Loading first و Loading second نمایش داده میشه. حالا اگه کامپوننت FirstSuspendingComponent کارش رو تموم کنه و بخواد که نمایش داده بشه, چون SecondSuspendingComponent هنوز کارش تموم نشده و revealOrder برابر together هست, اون هم همچنان Loading first رو نمایش میده و منتظر میمونه تا SecondSuspendingComponent کارش رو تموم کنه و اونموقع هردوشون باهم نمایش داده میشن.حتما دموی زیر رو ببینید تا نحوه کار SuspenseList رو بهتر متوجه بشید:دموhttps://github.com/facebook/react/pull/15902 http://vrgl.ir/ixPrR دیگر مقالات من: http://vrgl.ir/628wV  http://vrgl.ir/7Xs2l  http://vrgl.ir/EmGzx </description>
                <category>Eddie Cooro</category>
                <author>Eddie Cooro</author>
                <pubDate>Fri, 21 Jun 2019 20:58:44 +0430</pubDate>
            </item>
                    <item>
                <title>کارهای تکراری, ممنوع! (قسمت ۱)</title>
                <link>https://virgool.io/iran-react-community/%DA%A9%D8%A7%D8%B1%D9%87%D8%A7%DB%8C-%D8%AA%DA%A9%D8%B1%D8%A7%D8%B1%DB%8C-%D9%85%D9%85%D9%86%D9%88%D8%B9-%D9%82%D8%B3%D9%85%D8%AA-%DB%B1-numfwzclbnqj</link>
                <description>اصطلاح Don&#x27;t repeat yourself رو احتمالا خیلیامون شنیدیم, چیزی که شیرازه کار یه برنامه نویس خوب به شمار میاد. خودت رو تکرار نکن، ینی کدی که یک بار زدی رو یه فانکشن کن و بقیه جاها استفاده کن.برای منطقی که مشترکه یه کلاس (HOC/hook) بساز و همه جا استفاده کن. درکل وقتی چیزی رو بیشتر از دو بار قراره انجام بدیم، معمولا ایده خوبیه که به فکر نوشتنش بصورت جنرال باشیم.حتی چیزایی مثل react native هم برای همین اومدن. برای اینکه ما یک بار اپلیکیشنمون رو بنویسیم و روی android و ios استفاده کنیم.اما ما بعنوان برنامه نویس, خودمون یه دنیا کار های تکراری داریم که انجام میدیم. هر سری برای تبدیل class component به functional component بعضی کارهای تکراری رو انجام میدیم. گاهی اوقات برای ریفکتور کردن بخشی از کد مجبوریم یه تعداد زیادی خط شبیه به هم رو تغییر بدیم. و مثالی که قراره تو این ویدیو بررسیش کنم، میخوایم برای یه عالمه فیلد setter بنویسیم.میخوایم برای تک تک فیلد های سمت چپ, متدی شبیه عکس سمت راست بنویسیم. آیا باید ۱۰ بار یه کار تکراری رو دستی انجام بدیم؟لینک آپارات: لینک https://www.aparat.com/v/lkj8w  http://vrgl.ir/PjTel دیگر مقالات من: http://vrgl.ir/cFW91  http://vrgl.ir/7Xs2l  http://vrgl.ir/628wV </description>
                <category>Eddie Cooro</category>
                <author>Eddie Cooro</author>
                <pubDate>Sun, 16 Jun 2019 16:01:56 +0430</pubDate>
            </item>
                    <item>
                <title>سسِ مخصوصِ React context</title>
                <link>https://virgool.io/iran-react-community/react-context-secret-sauce-crvms21tzhwl</link>
                <description>چندوقتیه همه دارن از جایگزین کردن redux با context حرف میزنن, مخصوصا جدیدا با اومدن hook ها و api جدید و سرراست تر useContext, حجم مقالاتی که راجب استفاده از context بجای redux میبینیم بیشتر شده.از دید من اکثرشون صرفا redux رو مجددا با useContext و useReducer میسازن که ارزش افزوده زیادی نداره. در همین حین یه کتابخونه رو دیدم که تونسته از پتانسیل کامل Context استفاده کنه و برگ برنده‌ای رو رو کنه که باعث میشه استفاده ازش بجای redux بعضی وقتا منطقی باشه. (ویرایش:‌ این کتابخونه Context رو به همراه observed bits از پیاده‌سازی خودش حذف کرده. راجب دلایلش اینجا و این توییت سباستین رو بخونید)هرچند issue ها حاکی از اینن که تیم react-redux از مدت‌ها قبل از hook ها و این کتابخونه به فکر استفاده از این feature جذاب context بودن و تلاش هایی هم کردن, اما چیزی که باعث شده تا امروز شاهد پیاده سازی این feature توی react-redux نباشیم, یسری کاستی ها توی api خود react و همچنین unstable بودن این api عه.پس فعلا از https://github.com/dai-shi/react-hooks-global-state استفاده کنید و لذت ببرید اما اسراف نکنید :)تو ویدیوی زیر توضیح میدم این feature ای که حتی document هم نشده دقیقا چیه, چجوری میتونه به performance برناممون کمک کنه, و react-hooks-global-state چجوری ازش استفاده میکنه.لینک codesandboxلینک آپارات  https://www.aparat.com/v/w2vxE </description>
                <category>Eddie Cooro</category>
                <author>Eddie Cooro</author>
                <pubDate>Sun, 09 Jun 2019 22:04:36 +0430</pubDate>
            </item>
                    <item>
                <title>How to paginate in React/Redux like a hero</title>
                <link>https://virgool.io/iran-react-community/how-to-paginate-in-reactredux-like-a-hero-y0puyffsdj6v</link>
                <description>متن زیر ساختاریه که من توی چندتا پروژه برای paginate کردن با react/redux استفاده میکنم و نسبتا راضیم. امروز شخصی ازم درباره اینکه چجوری باید pagination رو توی ری‌اکت هندل کرد سوال پرسید, این مقاله جواب منه. اینجا هم منتشر میکنم تا اگه برای کسی مفید بود بتونه استفاده کنه 3&gt;خب واسه paginate کردن نظر به اینکه ریداکس داریممن یه همچین کاری میکنم:1- Reducers:میام هر اسلایس ریداکسم که قراره دیتاهای توش paginate شن رو با این ساختار درنظر میگیرم:https://gist.github.com/Eddie-CooRo/50c44ec633e6f1a2af1b86767d3ba138#file-slice-jsیعنی یه فیلد paginations داریم توی خود slice که راجبش پایینتر صحبت میکنیم, و یه فیلد data که همه دیتا های این slice رو به شکل یه آبجکت داره که key هر دیتا id اون دیتاس.حالا راجب paginations یه همچین ساختاری براش درنظر میگیریم:https://gist.github.com/Eddie-CooRo/50c44ec633e6f1a2af1b86767d3ba138#file-paginations-jsیعنی برا هر pagination ای که توی اپمون روی این دیتا میتونیم داشته باشیم یه فیلد جداگونه توی slice همین دیتا با اسم خاص خودش تعریف میکنیم که ۱- آیدی دیتا هایی که توی این pagination هستن رو به ترتیب توی یه آرایه ذخیره میکنه. ۲- لینکی که برا لود صفحه بعد نیازه  ۳- لینکی که برا لود صفحه قبل نیازه و ۴- لینکی که برا لود صفحه اول نیازه رو ذخیره میکنه.حالا با داشتن این تصویر ذهنی از slice های store مون میتونیم برای یوزرهامون همچین ردیوسری بنویسیم:https://gist.github.com/Eddie-CooRo/50c44ec633e6f1a2af1b86767d3ba138#file-userreducer-jsخب توی این reducer همونجوری که میبینی خیلی توجهی به paginations و چیزای مربوط بهش نکردیم, دلیلش اینه که اونارو توی یه higher order reducer هندل میکنیم چون خیلی جاها میخوایم استفاده کنیم:https://gist.github.com/Eddie-CooRo/50c44ec633e6f1a2af1b86767d3ba138#file-withpaginationhor-jsو بعد میتونیم اینجوری ازش استفاده کنیم:https://gist.github.com/Eddie-CooRo/50c44ec633e6f1a2af1b86767d3ba138#file-store-jsحالا هر slice ای که بخوایم رو میتونیم با اضافه کردن یه خط روش paginate بزنیم.2 - Action Creatorsدر ادامه actionCreator هارو هم خیلی راحت طبق همون اکشن هایی که داریم میسازیم من بعنوان مثال قضیه رو برای reload و loadMore پیش میبرم و حالت های loadPrevious و اینارو کاری نداریم:https://gist.github.com/Eddie-CooRo/50c44ec633e6f1a2af1b86767d3ba138#file-paginationactions-jsالبته اینا نسبتا ورژن ساده شده‌ و general شده‌ی چیزین که تو واقعیت استفاده میکنم.3- Selectorsمیشه برا راحتی کار selector های زیر رو هم اضافه کرد:https://gist.github.com/Eddie-CooRo/50c44ec633e6f1a2af1b86767d3ba138#file-selectors-js4- HOCو در آخر هم میتونیم یه همچین HOC ای داشته باشیم:https://gist.github.com/Eddie-CooRo/50c44ec633e6f1a2af1b86767d3ba138#file-withpaginationhoc-jsو هرجا که خواستیم ازش استفاده می‌کنیم:https://gist.github.com/Eddie-CooRo/50c44ec633e6f1a2af1b86767d3ba138#file-elsewhere-jsو یا:https://gist.github.com/Eddie-CooRo/50c44ec633e6f1a2af1b86767d3ba138#file-elsewhere2-jsو تمام :) ورژن تکست همه کدهای بالا توی این gist موجوده:https://gist.github.com/Eddie-CooRo/50c44ec633e6f1a2af1b86767d3ba138اگر هم هر سوالی داشتید میتونید توی تلگرام بهم پیام بدید.telegram: @Eddie_CooRo(توجه: تمامی کدهای بالا رو همین الان نوشتم و تست نشده ان, ممکنه ارور های ریزی داشته باشن که خود کامپایلر سرتون جیغ میکشه و میتونید درستش کنید, اگه چیزی بود گزارش کنید که من هم اصلاح کنم)</description>
                <category>Eddie Cooro</category>
                <author>Eddie Cooro</author>
                <pubDate>Wed, 05 Jun 2019 16:16:49 +0430</pubDate>
            </item>
                    <item>
                <title>فانکشنال js بدون درد و خونریزی - بخش دو compose</title>
                <link>https://virgool.io/JavaScript8/%D9%81%D8%A7%D9%86%DA%A9%D8%B4%D9%86%D8%A7%D9%84-js-%D8%A8%D8%AF%D9%88%D9%86-%D8%AF%D8%B1%D8%AF-%D9%88-%D8%AE%D9%88%D9%86%D8%B1%DB%8C%D8%B2%DB%8C-%D8%A8%D8%AE%D8%B4-%D8%AF%D9%88-compose-yhrl260eg1un</link>
                <description>فانکشن compose مثل ترکیب توابع توی ریاضیات عمل می‌کنهبرنامه نویسی فانکشنال ( تابعی D-: ) جدیدا خیلی رو بورسه, چون کمک میکنه برناممون منطقی تر رفتار کنه, مخصوصا وقتی بحث مولتی تردینگ میاد وسط.چندروز پیش سر یکی از کلاس هام فهمیدم یاد دادنش اونقدرا هم راحت نیست, دقیقا همونجوری که هممون یه زمانی برای یاد گرفتن class و object و polymorphism کلی اذیت شدیم, الان هم یه کوچولو تقلا لازمه تا پایه های موضوع برامون جا بیافته.توی پست قبلی راجب reduce صحبت کردیم که کمکمون میکنه یه آرایه رو به یک &quot;چیز&quot; تبدیل کنیم و گفتیم که این &quot;چیز&quot; جهان شموله ?توی این پست یکی از کاربرد های خیلی جذاب reduce رو نشون میدم, یعنی فانکشن compose. این فانکشن (و داداشش, pipe) بهمون اجازه میدن فانکشن های کوچولو داشته باشیم که کارهای کوچولو میکنن و درنهایت خیلی راحت بتونیم باهم ترکیبشون کنیم تا یه کار پیچیده رو انجام بدیم.پس بریم که داشته باشیم ویدیوی compose رو:https://www.aparat.com/v/QR63l https://www.aparat.com/v/QR63l </description>
                <category>Eddie Cooro</category>
                <author>Eddie Cooro</author>
                <pubDate>Mon, 29 Apr 2019 02:30:57 +0430</pubDate>
            </item>
                    <item>
                <title>فانکشنال js بدون درد و خونریزی - بخش یک reduce</title>
                <link>https://virgool.io/JavaScript8/%D9%81%D8%A7%D9%86%DA%A9%D8%B4%D9%86%D8%A7%D9%84-js-%D8%A8%D8%AF%D9%88%D9%86-%D8%AF%D8%B1%D8%AF-%D9%88-%D8%AE%D9%88%D9%86%D8%B1%DB%8C%D8%B2%DB%8C-%D8%A8%D8%AE%D8%B4-%DB%8C%DA%A9-reduce-tghl6fzl5r8u</link>
                <description>پیاده سازی reduce با جاوااسکریپت خالی خالی :)برنامه نویسی فانکشنال ( تابعی D-: ) جدیدا خیلی رو بورسه, چون کمک میکنه برنامه امون منطقی تر رفتار کنه, مخصوصا وقتی بحث مولتی تردینگ میاد وسط.چندروز پیش سر یکی از کلاس هام فهمیدم یاد دادنش اونقدرا هم راحت نیست, دقیقا همونجوری که هممون یه زمانی برای یاد گرفتن class و object و polymorphism کلی اذیت شدیم, الان هم یه کوچولو تقلا لازمه تا پایه های موضوع برامون جا بیافته.توی این پست (و پست بعدی)‌ سعی کردم تا جایی که تونستم کمکتون کنم که reduce و compose رو بدون درد و خونریزی یاد بگیرید.پس بریم که داشته باشیم ویدیوی اول رو: https://www.aparat.com/embed/1l2nI?data[rnddiv]=46882348294&amp;data[responsive]=yes  https://www.aparat.com/v/1l2nI  http://vrgl.ir/wbp7L </description>
                <category>Eddie Cooro</category>
                <author>Eddie Cooro</author>
                <pubDate>Mon, 29 Apr 2019 01:29:23 +0430</pubDate>
            </item>
            </channel>
</rss>