مقدمة
لو الـ Initial Value لـ useState عندك computationally expensive (مثلا بتروح تقرأها من الـ LocalStorage، العملية دي بتكون Expensive عشان انت بتقرأ من الـ Hard drive الخاص باليوزر) أستخدم الـ Lazy Initialization!
المشكلة اللي بتحصل بسبب الـ Rerendering
الـ Lazy Initialization هو أنك بدل ما تباصي الـ Value نفسها للـ useState، انت هتباصي function بترجع الـ value دي. طيب ليه؟
لو انت روحت عملت كده:
const [value, setValue] = React.useState(
window.localStorage.getItem("someValue")
);
أو كده:
const getLocalStorageValue = () => window.localStorage.getItem("someValue");
React.useState(getLocalStorageValue());
ففي كل مرة هيحصل Re-rendering انت هتقرأ من الـ LocalStorage، والـ value اللي انت بتقرأها دي في الـ re-rendering ملهاش لزمة لأن React بتستخدمها كـ Initial State بس، وبعد كده بتحتفظ بالـ value ما بين الـ re-rendering. فأنت كده عمال بتعمل IO Operations ملهاش لزمة!
الحل باستخدام Lazy Initialization
الحل انك تباصي لـ useState فانكشن بترجع الـ Initial State، واللي هيحصل ان React هتنادي الفانكشن دي مرة واحدة بس لما الـ Component يتعمله Mount. الصورة المرفقة بتوضح ده. الـ Lazy initializers بيحصلها call مرة واحدة في البداية وبعد كده اثناء الـ Update/Re-rendering مبيحصلهاش Call.
يعني انت مفروض تعمل كده:
const [value, setValue] = React.useState(() =>
window.localStorage.getItem("someValue")
);
أو كده:
const getLocalStorageValue = () => window.localStorage.getItem("someValue");
React.useState(getLocalStorageValue);
