useMemo — qimmat hisoblashlarni keshlash, qachon kerak

~15 daq · React · Hooks — Asosiy

Muammo: har render da qayta hisoblash

Komponent qayta chizilganda — ichidagi hamma kod qayta ishlaydi. Agar og'ir hisoblash bo'lsa — har render da qayta hisoblanadi.

function Statistika({ raqamlar, filtr }) {
  const [boshqaState, setBoshqaState] = useState(0);

  // Bu hisoblash har render da ishlaydi
  // raqamlar o'zgarmasa ham, boshqaState o'zgarganda ham
  const yigindi = raqamlar
    .filter(r => r > filtr)
    .reduce((sum, r) => sum + r, 0);

  return (
    <div>
      <p>Yig'indi: {yigindi}</p>
      <button onClick={() => setBoshqaState(s => s + 1)}>
        Boshqa narsa: {boshqaState}
      </button>
    </div>
  );
}

boshqaState o'zgarganda — yigindi qayta hisoblanadi. Lekin raqamlar va filtr o'zgarmagan — natija ham o'zgarmaydi. Bu behuda ish.


useMemo qanday ishlaydi?

import { useMemo } from 'react';

function Statistika({ raqamlar, filtr }) {
  const [boshqaState, setBoshqaState] = useState(0);

  const yigindi = useMemo(() => {
    return raqamlar
      .filter(r => r > filtr)
      .reduce((sum, r) => sum + r, 0);
  }, [raqamlar, filtr]); // faqat bular o'zgarganda qayta hisoblanadi

  return (
    <div>
      <p>Yig'indi: {yigindi}</p>
      <button onClick={() => setBoshqaState(s => s + 1)}>
        Boshqa narsa: {boshqaState}
      </button>
    </div>
  );
}
┌─────────────────────────────────────────────────┐
│  boshqaState o'zgardi → re-render               │
│  useMemo: raqamlar va filtr o'zgarmadi          │
│  → keshdan oladi, qayta hisoblamaydi ✅          │
└─────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────┐
│  filtr o'zgardi → re-render                     │
│  useMemo: filtr o'zgardi                        │
│  → qayta hisoblaydi, yangi natija saqlaydi ✅   │
└─────────────────────────────────────────────────┘

Qachon useMemo kerak?

useMemo ning o'zi ham xarajat — kesh saqlash, dependency solishtirish. Har joyga qo'yish — aksincha sekinlashtiradi.

Kerak bo'lgan holat:

// ✅ Katta massiv ustida og'ir hisoblash
const natija = useMemo(() => {
  return minglarMassiv
    .filter(...)
    .sort(...)
    .map(...);
}, [minglarMassiv]);

Kerak bo'lmagan holat:

// ❌ Ortiqcha — oddiy hisoblash uchun useMemo shart emas
const yigindi = useMemo(() => a + b, [a, b]);

// ✅ Shunchaki yozing
const yigindi = a + b;

Qoida: avval yozing, sekin bo'lsa — o'lchang, keyin optimizatsiya qiling. Ko'r-ko'rona useMemo qo'yish — kod murakkabligini oshiradi, foyda bermaydi.


useMemo bilan ob'ekt yaratish

useMemo ning yana bir foydali ishi — ob'ekt yoki massivni "barqaror" qilish.

function Komponent({ id }) {
  // ❌ Har render da yangi ob'ekt yaratiladi
  // bola komponent buni "o'zgardi" deb o'ylaydi
  const sozlamalar = { id, rang: 'ko\'k' };

  // ✅ id o'zgarmasa — xuddi shu ob'ekt qaytariladi
  const sozlamalar = useMemo(
    () => ({ id, rang: 'ko\'k' }),
    [id]
  );

  return <BolaKomponent sozlamalar={sozlamalar} />;
}

Bu React.memo bilan birgalikda muhim — keyingi darslarda ko'ramiz.


Xulosa

useMemo(() => hisoblash, [dependency])
           │                   │
           │                   └── bular o'zgarganda qayta hisoblaydi
           └── natija keshlanadi
  • Og'ir hisoblash (katta massiv filter/sort/map) → useMemo
  • Oddiy hisoblash → shunchaki yozing
  • Avval yozing, sekin bo'lsa o'lchang, keyin useMemo

Keyingi dars

16-dars: useCallback — funksiyani keshlash, qachon kerak, useMemo farqi