چرا فراخوانی متد setState در React بلافاصله حالت را تغییر نمیدهد؟
این پرسش به نحوه عملکرد setState در React و چگونگی عدم تغییر فوری حالت میپردازد. هنگامی که setState را فرا میخوانید، React حالت را به طور فوری تغییر نمیدهد، بلکه یک انتقال حالت در حال انتظار ایجاد میکند. دسترسی به this.state پس از فراخوانی این متد، ممکن است مقدار موجود را برگرداند. هیچ تضمینی برای عملیات همزمان فراخوانیهای setState وجود ندارد و ممکن است برای افزایش کارایی، فراخوانیها به صورت دستهای انجام شوند.
در مثال ارائه شده، دلیل اینکه خروجی دوم console.log در تابع handleChange همان مقدار خروجی اول را نشان میدهد، همین عدم همزمانی است. setState به صورت ناهمگام کار میکند و بلافاصله حالت را بروزرسانی نمیکند. بنابراین، console.log دوم قبل از بروزرسانی واقعی حالت اجرا میشود.
برای اجرای کدی پس از تغییر حالت، میتوان از دو روش استفاده کرد:
روش اول: استفاده از تابع بازگشتی در
میتوان یک تابع بازگشتی را به عنوان آرگومان دوم به setState پاس داد. این تابع پس از بروزرسانی حالت و قبل از رندر مجدد اجزا اجرا میشود. این رویکرد برای اعمال منطقی که به بروزرسانی حالت وابسته است، مناسب است:
this.setState({value: event.target.value}, function () {
console.log(this.state.value);
});
روش دوم: استفاده از متد چرخه حیات
متد componentDidUpdate پس از هر بروزرسانی حالت و رندر مجدد اجزا فراخوانی میشود. این رویکرد به خصوص زمانی مفید است که چندین setState متوالی فراخوانی شود و بخواهید یک تابع خاص را پس از هر تغییر حالت اجرا کنید. این روش نسبت به اضافه کردن تابع بازگشتی به هر setState ترجیح داده میشود. میتوانید در داخل componentDidUpdate منطق خاصی را بر اساس مقادیر قبلی و جدید حالت پیادهسازی کنید:
componentDidUpdate(prevProps, prevState) {
if (this.state.value !== prevState.value) {
this.foo();
}
}
استفاده از async/await به طور مستقیم مساله همزمانی setState را حل نمیکند، زیرا await تنها میتواند به Promise ها اعمال شود، و setState به طور مستقیم Promise برنمیگرداند. بنابراین این روش پیشنهاد نمیشود.
در نهایت، توجه به این نکته مهم است که به منظور کنترل رندر بر اساس کارهایی که در تابع بازگشتی انجام میدهید، میتوانید از shouldComponentUpdate استفاده کنید. این متد به شما اجازه میدهد قبل از رندر مجدد، تعیین کنید که آیا نیاز به بروزرسانی اجزا هست یا خیر. این روش میتواند برای بهینهسازی عملکرد اجزا در مواقعی که تغییرات حالت تاثیر قابل توجهی در رندر ندارند، مورد استفاده قرار گیرد.