React setState عدم بهروزرسانی وضعیت
شرح مسئله
در این کد، متغیر total حاصل جمع اعداد موجود در آرایه newDealersDeckTotal است و مقدار صحیح را نشان میدهد. با این حال، پس از فراخوانی setState برای بهروزرسانی dealersOverallTotal در وضعیت کامپوننت، مقدار dealersOverallTotal در خروجی کنسول مقدار صحیح را نشان نمیدهد. حتی با استفاده از setTimeout نیز مشکل برطرف نمیشود.
let total = newDealersDeckTotal.reduce(function(a, b) {
return a + b;
},
0);
console.log(total, 'tittal'); // خروجی صحیح total
setTimeout(() => {
this.setState({ dealersOverallTotal: total });
}, 10);
console.log(this.state.dealersOverallTotal, 'dealersOverallTotal1'); // خروجی ناصحیح
newDealersDeckTotal یک آرایه از اعداد مانند [1, 5, 9] است.
راه حل
مشکل اصلی ناشی از ماهیت ناهمزمان تابع setState در React است. این تابع بهطور معمول بهصورت ناهمزمان اجرا میشود، به این معنی که بلافاصله پس از فراخوانی آن، وضعیت کامپوننت بهروز نمیشود. بنابراین، console.log بلافاصله پس از setState مقدار قبلی را نشان میدهد.
برای حل این مشکل، باید از تابع callback که در setState قابل ارائه است، استفاده کنید. این تابع پس از اتمام بهروزرسانی وضعیت اجرا میشود و تضمین میکند که مقدار صحیح را دریافت خواهید کرد:
this.setState({ dealersOverallTotal: total }, () => {
console.log(this.state.dealersOverallTotal, 'dealersOverallTotal1');
});
توجه داشته باشید که قبل از فراخوانی setState، مقدار وضعیت را log میکنید. این باعث میشود که مقدار قبل از بهروزرسانی را مشاهده کنید. استفاده از callback در setState این مشکل را برطرف میکند و اطمینان میدهد که مقدار console.log پس از بهروزرسانی وضعیت، مقدار صحیح را نمایش میدهد.
در مورد استفاده از هوکها در React، اگر از هوکهای functional component استفاده میکنید، برای مشاهده تغییرات وضعیت، باید از هوک useEffect استفاده کنید:
const [fruit, setFruit] = useState('');
setFruit('Apple');
useEffect(() => {
console.log('Fruit', fruit);
}, [fruit])
useEffect با هر بار رندر مجدد کامپوننت اجرا میشود. اگر آیتمهای pass شده به آرایه (در این مثال، fruit) تغییر کنند، useEffect نیز اجرا میشود و console.log بهروزرسانی را نشان میدهد. بهعبارت دیگر، useEffect یک مکان مناسب برای پاسخ به تغییرات در وضعیت است.
در نهایت، به یاد داشته باشید که setState یک عملیات ناهمزمان است و باید همیشه از callback یا useEffect (در صورت استفاده از هوکها) برای اطمینان از مشاهده بهروزرسانیها استفاده کنید.
`