💡 Coding tips
🌱 From my real experiences
Instagram:@_perfino
@per_fino
Post #110
67
Perfino🌱 {ریکت}: همیشه میگن " state رو mutate نکن " خب این یعنی چی؟ 1. اول معنی خود کلمه Mutation یعنی تغییر دادن چیزی در جای خودش، بدون ساختن نسخه جدید 2. چه چیزهایی mutate میکنند؟ Mutation روی چیزهایی معنا دارد که قابل تغییر هستند. در جاوااسکریپت اینها…
حالا چرا در ریاکت میگوییم state را mutate نکن؟
برگرد به مفهوم snapshot که در پیام قبلی گفتم. ریاکت برای اینکه بفهمد state عوض شده، به هویت مرجع (reference identity) نگاه میکند، نه به محتوایش.
بگذار با کد نشان بدهم:
const [todos, setTodos] = useState([{ id: 1, text: 'خرید' }]);
function addTodo() {
// این غلط است
todos.push({ id: 2, text: 'ورزش' });
setTodos(todos);
}
return (
<ul>
{todos.map(t => <li key={t.id}>{t.text}</li>)}
</ul>
);
}چه اتفاقی میافتد وقتی addTodo اجرا شود؟
1. todos.push(...) آرایهی فعلی را در جای خودش تغییر میدهد.
2. حالا todos هنوز همان مرجع قبلی است. همان آدرس حافظه. فقط محتوایش عوض شده.
3. setTodos(todos) صدا زده میشود، اما todos همان reference قبلی است.
4. ریاکت میگوید: «مرجع عوض نشده. پس این state تغییر نکرده.» و رندر دوباره را انجام نمیدهد.
5. UI آپدیت نمیشود. آیتم جدید نمایش داده نمیشود.
این باگ کلاسیک mutation است. کد بهنظر درست کار میکند اما UI عوض نمیشود.
۴. نسخه درست همان کد
const [todos, setTodos] = useState([{ id: 1, text: 'خرید' }]);
function addTodo() {
// این درست است
setTodos([...todos, { id: 2, text: 'ورزش' }]);
}
return (
<ul>
{todos.map(t => <li key={t.id}>{t.text}</li>)}
</ul>
);
}اینجا چه کردیم؟
· [...todos, newItem] یک آرایه جدید ساخت. آرایه قبلی دستنخورده مانده.@perfino_com
· این آرایه جدید مرجع جدیدی دارد.
· setTodos این مرجع جدید را میگیرد.
· ریاکت میبیند مرجع عوض شده، پس رندر دوباره میکند.
· UI آپدیت میشود.
این تفاوت بین mutation و immutable update است.




