CTO at liara.ir
آیا واقعا عمر Redux به سر رسیده است؟
چند روزیست که در جامعهی توسعهدهندگاه React، درمورد قابلیتهای جدید نسخهی 16.3 این کتابخانه، صحبت میکنند. لباس جدیدی که Context بر تن خود کرده، از قابلیتهایی است که حسابی جلب توجه کرده است. اگر مایل هستید درمورد تمام اتفاقاتی که قرار است در این نسخه بیافتد، مطلع شوید، این مقاله را مطالعه کنید.
مقالات و بازخوردهای مختلفی دربارهی API جدیدی که برای Context طراحی شده، منتشر شدهاست. یکی از مباحثی که در این مقالات و بازخوردها به آن اشاره شده، جایگزین کردن ریداکس (Redux) با Context بودهاست. سوالی که میخواهیم در این نوشته به پاسخ آن برسیم، این است که آیا واقعا عمر ریداکس به سر رسیده است؟
مرغ اول وجود داشت یا تخم مرغ؟
ممکن است فکر کنید که قابلیت Context، قابلیتی است که به تازگی قرار است به React اضافه شود. اما اینگونه نیست. شاید بتوان گفت که از همان اول با React همراه بوده. اما چیزی که در نسخهی 16.3 مطرح شده، شکل جدیدی از این قابلیت است. با API جدیدی که React برای کار با Context در اختیارمان قرار میدهد، استفاده از این قابلیت بسیار سادهتر شده و مشکلات خاصی هم که قبلا وجود داشت، حل خواهند شد. پس میتوان گفت که: زمانی که ریداکس معرفی شد، قابلیت Context در React وجود داشت. پس چرا در آن زمان، کسی مستقیما از Context استفاده نمیکرد؟
چرا باید از Context استفاده کنیم؟
اگر به برنامهای که با React نوشته شده نگاهی بیاندازیم، خیلی راحت میشود جریانی که دادهها طی میکنند را مشاهده و دنبال کرد. وقتی کامپوننتی را بررسی کنید، میتوانید ببینید که چه دادههایی از طریق prop به آن پاس داده شده است.
اما آیا تا به حال شما هم بابت منتقل کردن یک prop به چندین لایه پایینتر اذیت شدهاید؟ زمانی که یک prop را مجبوریم از بین کامپوننتهای میانی انتقال دهیم تا به آن کامپوننتی که آن را لازم دارد، برسد؟
در این زمان، کتابخانههای مدیریتکنندهی وضعیت برنامه (State Managers)، مثل ریداکس به چشم میآیند. با استفاده از ریداکس، در هر نقطهای از برنامه، میتوانیم یک کامپوننت را به store وصل یا همان connect کنیم تا بتواند دادههای مورد نیازش را از آن بخواند. برای اینکار، فقط باید کل برنامه را، داخل کامپوننتی به نام Provider قرار دهیم. بیشتر شبیه جادوست.
اما جادویی در کار نیست!
لازم است که بدانیم ریداکس با استفاده از Context این کار را میکند. کل state برنامه را داخل Context قرار میدهد و Context همان چیزیست که میتوان از آن برای انتقال غیر مستقیمِ دادهها و توابع استفاده کرد.
تا به امروز، استفاده کردن از Context در برنامهها نهی شدهاست. اگر نگاهی به مستندات React بیاندازید، متوجه میشوید که توسعهدهندگانِ محترمِ React سه بارِ متوالی هشدار میدهند که از این قابلیت بهصورت مستقیم در برنامهیتان استفاده نکنید. چون این قابلیت آزمایشی است و ممکن است در آینده تغییر کند. ضمنا باعث پیچیدگیهایی هم خواهد شد و نوشتن unit test را هم سختتر میکند.
این سر و صدایی که این روزها بابت تغییراتی که در Context رخ داده، بهپا شده است، بیشتر برای شکل جدید و جذابی است که به خود گرفته:
با استفاده از این شکل و شمایل جدید و همچنین پایدار شدن آن، دیگر خبری از هشدارهای React نخواهد بود و میتوان از آن با خیالت راحت استفاده کرد. در چنین شرایطی، میتوانیم امیدوار باشیم که لازم نیست بابت مشکلِ انتقال prop ها به لایههای پایینتر، از ریداکس و سایر State Manager ها استفاده کنیم. بدین ترتیب، بسیاری از پروژهها، خیلیزود درگیر Redux نخواهند شد و شاید فقط آن زمانی که به ویژگیهای خاص آن نیاز داشته باشند، سراغ آن بروند.
و این یعنی خداحافظ Redux؟
نه! این قابلیت جدید، به هیچ عنوان قرار نیست که جای Redux را بگیرد.
مشکلی که ریداکس قصد حل کردن آن را داشت، دلپذیرتر کردن Flux بود. مشکلی هم که Flux قصد حل کردن آن را داشت، Predictable State Flow یا همان «جریان قابل پیشبینی وضعیت برنامه» است. که این باعث بهبود فرآیند دیباگ کردن وضعیت برنامه میشود و میتوان بهراحتی تغییراتی که در وضعیت برنامه رخ میدهد را دنبال کرد.
اگر برایتان مهم است که بدانید چه زمانی، قسمت خاصی از state تغییر کرد و آن تغییر از کجا آمد؟ چه چیزی باعث آن شد؟ میتوانید از ریداکس بهترین نتیجه را بگیرید. ریداکس برای فراهم کردن چنین امکانی، با شما قراردادی میبندد:
- وضعیت برنامه (application state) را در قالب object و array های ساده تعریف کنید.
- تغییراتی که باید در state رخ دهد را با استفاده از object های ساده تعریف کنید. (actions)
- منطقی که باید به تغییرات در state رسیدگی کند را با pure function ها تعریف کنید. (reducers)
رعایت هیچ کدام از این قوانین و محدودیتها برای ساختن یک برنامه ضروری نیستند، چه با React و چه بدون آن. در واقع اینها قوانین و محدودیتهای سختگیرانهای هستند و قبل از رعایت آنها، باید فکر کنید که آیا برنامهی شما نیازی به آنها دارد یا نه.
آیا دلایلی دارید که این قوانین سرسختانه را در برنامهیتان اعمال کنید؟
این محدودیتها، زمانی جذاب میشوند که بخواهید چنین چیزهایی را انجام دهید:
- وضعیت برنامه (state) را داخل Local Storage ذخیره کنید تا وقتی دوباره وارد صفحه میشوید، از همان نقطه بتوانید ادامه دهید. یعنی با refresh کردن، چیزی از دست نرود.
- وضعیت برنامه (state) را در سرور تعیین کنید، آن را به کلاینت داخل HTML بفرستید و سپس از همان نقطه کاربر بتواند با برنامه کار کند (Server Rendering).
- تمام عملهایی که کاربر انجام میدهد یا به عبارتی تمام action هایی که ایجاد میکند را به همراه یک نسخه از وضعیت برنامه (state) را میتوانید در کنار هم قرار داده و در جایی ذخیره کنید. در این صورت، توسعهدهندگان محصول میتوانند دقیقا همان action ها را اجرا کنند تا ببیند کاربر چه مراحلی را طی کرده و به مشکل برخورده است تا بهتر بتوانند خطاها را رفع کنند.
- قابلیت Undo کردن را به کاربر بدهید. وقتی کاربر عملی را انجام داد، بتواند به وضعیت قبلی برگردد.
- در هنگام توسعه، میتوانید بین action ها جابهجا شوید، به آینده بروید یا به گذشته برگردید. به نظر میرسد سفر در زمان با Redux به واقعیت تبدیل شدهاست.
در هر حال، زمانی به سراغ Redux بروید که دیگر متد setState جوابگو نیست. ریداکس فرآیند توسعهی برنامهیتان را بسیار تحت تاثیر قرار خواهد داد، بنابراین در انتخاب این چارچوب برای پروژهتان، احتیاط کنید.
اگر برای انجام دادن چیزهای مختلف به روشی که Redux پیشنهاد میدهد، دچار فشار و سختی میشوید، احتمالا شما یا همتیمیهایتان، آنرا بسیار جدی گرفتهاید. Redux فقط یک ابزار است، مثل سایر ابزارهایتان.
حرفِ آخر
شکل و شمایل تازهای که Context به خود گرفته، باعث از بین رفتن Redux نخواهد شد. در واقع میتوانیم امیدوار باشیم که از ریداکس در جای مناسبِ خود استفاده خواهد شد و لازم نخواهد بود که توسعهدهندگان برای مشکل انتقال prop ها به لایههای پایینتر، از آن استفاده کنند. ریداکس قوانینی تعریف کرده تا بتواند مشکلات خاصی را که در بعضی برنامهها وجود دارد را حل کند. برای حل این مشکلات، خودِ ریداکس هم از Context استفاده میکند. به نوعی، یک لایهی جدید روی Context است که یکسری قابلیتهای جدید را به شما میدهد.
هر ابزاری قابلیتهای خاص خودش را دارد و اگر بدون منطق و فقط از روی معروفیت و شهرتی که آن ابزار دارد بخواهیم از آن استفاده کنیم، ممکن است هم خودمان را اذیت کنیم و هم پروژهیمان را درگیر پیچیدگیهای بیمورد کنیم.
مطلبی دیگر از این انتشارات
اسکیما ولدیشن در ریداکس
مطلبی دیگر از این انتشارات
جست و جوی نقشه با استفاده از mapbox و ReactJS
مطلبی دیگر از این انتشارات
اجرای ریاکت سمت سرور (React SSR)