طرح پیشنهادی React Hooks با برخی هوکهای داخلی میآید که بر روی انجام یک کار، مانند فراهم کردن state یا محتویات به یک کامپوننت تابع تمرکز میکنند. شما همچنین میتوانید خودتان از این ابزار برای تشکیل بلوکهای ساخت استفاده کنید.
در این پست، به اعماق چیزی که من آن را مهمترین هوک در نظر میگیرم وارد خواهیم شد: useState.
در هنگام نوشتن این مقاله، هوکها یک طرح آزمایشی هستند. هیچ یک از مطالب این پست نباید قطعی در نظر گرفته شود. لطفا این مسئله را به خاطر داشته باشید.
هوکها در نسخه 16.7.9-alpha از React در دسترس هستند. من یک صفحه در وبسایت CodeSandbox راهاندازی کردهام که اگر میخواهید با مثال موجود در این پست ادامه دهید، این صفحه سریعا شما را پیش خواهد برد.
React state امروز
اگر یک کامپوننت stateful در React میخواهید، در حال حاضر تنها گزینهتان این است که آن کامپوننت را به عنوان یک کلاس بنویسید. این مسئله برای من یک مرجع ناامیدی بوده است. اغلب من خود را در حال مصرف مقدار زیادی انرژی ذهنی، برای فکر کردن درباره این که آیا میخواهم یک تابع بی نقص را در قالب یک کلاس بازسازی کنم تا مقداری state در آن نگه دارم یا نه، مییابم.
من خود را قانع میکنم که جلوگیری از یک بازسازی این چنینی به نفع من است. در نهایت هم خود را در میان استراتژیها، کتابخانهها و راه حلهای دیگر برای مدیریت state، مییابم.
اگر همه چیز واقعا بد پیش برود، شروع به پرسیدن این که آیا کامپوننت مورد نظر اصلا state را نیاز دارد، یا نه خواهم کرد. به گونهای که انگار باید از آن جلوگیری شود.
این کار به نظر بیش از حد میآید، و احتمالا هم همینطور است. اما این اتفاق پیش آمده است و اگر زمان قابل توجهی را صرف کار با React کرده باشید، شما هم ممکن است خود را در این مخمصه بیابید.
اضافه کردن state به یک کامپوننت باید طبیعی به نظر بیاید، اما وقتی که در حال نوشتن یک کلاس هستم، داشتن حس طبیعی سخت است.
وارد هوک useState شوید
کامپوننتهای تابع با استفاده از هوک useState، حال میتوانند state محلی را نگه دارند.
useState یک تابع است که یک state اولیه را تقبل میکند و آرایهای دارای ۲ آیتم را بر میگرداند:
۱. state فعلی.
۲. یک تابع که میتواند فراخوانی شود تا state را بروزرسانی کند.
به علت روشی که تخریب آرایه کار میکند، ما میتوانیم آیتمهای برگردانده شده توسط useState را هر چیزی که میخواهیم نامگذاری کنیم. هیچ محدودیتی توسط یک API برای ما تعیین نشده است. به نظر میرسد که اکوسیستم React به سمت سینتکس [value, setValue] پیش میرود.
در مثال بالا، color مقدار state است و در ابتدا با مقدار «GREEN» شروع میشود. تابع setColor میتواند فراخوانی شود تا آن مقدار را بروزرسانی کند.
دقت کنید که بر خلاف یک کامپوننت کلاس، state در یک کامپوننت تابع نیازی به یک آبجکت ندارد. در اینجا فقط یک رشته است.
یک نکته مهم دیگر این است که تابع بروزرسانی که در این مورد setColor میباشد، state جدید را با state فعلی ادغام نمیکند؛ بلکه در عوض آن را به کلی بازنویسی میکند. این نسبت به نحوه کار this.setState در کامپوننتهای کلاس متفاوت است.
بروزرسانی state
مقدار color بین رندرهای مجدد حفظ خواهد شد، مگر این که تابع setColor با یک مقدار جدید فراخوانی شود:
وقتی که بر روی دکمه کلیک میشود، تابع slow تابع setColor را با مقدار «YELLOW» فراخوانی خواهد کرد. این باعث خواهد شد که کامپوننت StreetLight مجددا رندر شود. وقتی که شد، متغیر color به مقدار «YELLOW» بروزرسانی خواهد شد.
صبر کنید، چطور شد؟
در نگاه اول فکر خواهید کرد که هر زمان StreetLight رندر میشود، این تابع useState را با مقدار «GREEN» فراخوانی میکند. پس color چگونه میتواند چیزی به جز سبز باشد؟
این یک سوال منطقی است. در اینجا چند خط از سند React را مشاهده مینمایید که ممکن است درک این مفهوم را برای شما سادهتر کنند:
«معمولا متغیرها وقتی که تابع وجود دارد، اما متغیرهای state توسط React حفظ شدهاند، ناپدید میشوند.»
«React مقدار فعلی خود را در میان رندرهای مجدد به یاد خواهد داشت، و آخرین مورد را برای تابع ما فراهم خواهد کرد.»
«ممکن است برایتان سوال باشد که: چرا useState در عوض createState نامگذاری نشده است؟ create خیلی دقیق نخواههد بود؛ زیرا state فقط در اولین باری که کامپوننت ما رندر میشود، ساخته میشود. در طی رندرهای بعدی، useState به ما state فعلی را میدهد.»
اما چگونه؟
جادویی در کار نیست، بلکه همه چیز JavaScript است
به زبان ساده، React رد تمام فراخوانیهای useState برای هر کامپوننت را به صورت داخلی نگه میدارد. همچنین React یک mapping بین تابع بروزرسانی و مقدار state برای هر آنچه که بروزرسانی میکند، خواهد ساخت.
مقدار اولیه که به useState منتقل میشود، در هنگام اولین رندر برگردانده میشود، اما React از آنجا مقدار صحیح را بر پایه mapping مورد نظر بر خواهد گرداند. همچنین React از map مورد نظر برای دانستن این که وقتی تابع بروزرسانی فراخوانی میشود، کدام قطعه state را جهش دهد استفاده میکند.
ممکن است این مسئله برای شما مبهم به نظر بیاید، و شما تنها شخصی نیستید که چنین حسی دارد. من هم توسط نحوه انجام این کار گیج شده بودم. وقتی که پی بردم شما میتوانید چندین فراخوانی به useState در یک کامپوننت مشابه داشته باشید، گیجی من حتی بیشتر شد:
شما میتوانید این کار را با محتویات خود انجام دهید.
React چگونه رد state را نگه میدارد؟
برای عملی شدن این مسئله، React انتظار دارد که شما از چند قانون پیروی کنید:
۱. هوکها را فقط در بالاترین سطح یک تابع فراخوانی کنید.
۲. هوکها را فقط از کامپوننتهای تابع و هوکهای سفارشی فراخوانی کنید.
React این قوانین را به این دلیل اعمال میکند که در واقع به ترتیب فراخوانی هوکها، برای مدیریت صحیح دادهها تکیه میکند. این قوانین ممکن است در ابتدا بی ثبات به نظر برسند، اما پیروی از آنها سخت نیست. و البته من نمیتوانم به سناریوای فکر کنم که بخواهید آنها را زیر پا بگذارید.
جمع بندی
به نظر من useState یک بلوک ساخت است. شما میتوانید از آن به گونهای استفاده کنید که انگار ساخته شده است تا برای کامپوننتهای تابع شما state را فراهم کند، یا این که میتوانید از آن برای چکیدهسازی منطق stateful در هوکهای سفارشی استفاده کنید.
من باور دارم که هوکهای سفارشی قرار است بزرگترین ابرقدرتی باشند که توسعه دهندگان React وقتی که نسخه 16.7 منتشر میشود، به دست بیاورند و useState هم اساس آنها است. امیدوارم این مقاله برای شما کاربردی بوده باشد.
- مقاله مرتبط: انتقال state میان کامپوننتها در ReactJS
دیدگاه و پرسش
در حال دریافت نظرات از سرور، لطفا منتظر بمانید
در حال دریافت نظرات از سرور، لطفا منتظر بمانید