useCallback — funksiyani keshlash, qachon kerak, useMemo farqi

~15 daq · React · Hooks — Asosiy

Muammo: har render da yangi funksiya

JavaScript da funksiya — ob'ekt. Har render da funksiya qayta yaratiladi — yangi ob'ekt, yangi xotira manzili.

function Ota() {
  const [son, setSon] = useState(0);

  // Har render da yangi funksiya yaratiladi
  function bosish() {
    console.log('bosildi');
  }

  return (
    <div>
      <Bola onClick={bosish} />
      <button onClick={() => setSon(s => s + 1)}>Re-render</button>
    </div>
  );
}
1-render: bosish → 0x001 (xotira manzili)
2-render: bosish → 0x002 (yangi funksiya, yangi manzil)
3-render: bosish → 0x003

Bola komponentiga har safar yangi funksiya beriladi. React.memo bilan optimizatsiya qilingan Bola ham "props o'zgardi" deb qayta chiziladi — chunki funksiya har safar yangi.


useCallback qanday ishlaydi?

import { useCallback } from 'react';

function Ota() {
  const [son, setSon] = useState(0);

  const bosish = useCallback(() => {
    console.log('bosildi');
  }, []); // dependency o'zgarmasa — xuddi shu funksiya qaytariladi

  return (
    <div>
      <Bola onClick={bosish} />
      <button onClick={() => setSon(s => s + 1)}>Re-render</button>
    </div>
  );
}
1-render: bosish → 0x001
2-render: bosish → 0x001  ← xuddi shu (keshdan)
3-render: bosish → 0x001  ← xuddi shu

Bola "props o'zgarmadi" deb qayta chizilmaydi.


useMemo vs useCallback

useMemo    → qiymatni keshlaydi
useCallback → funksiyani keshlaydi

// Bu ikkalasi bir xil:
useMemo(() => () => doSomething(), [dep])
useCallback(() => doSomething(), [dep])

Amalda:

  • Hisoblash natijasi kerak → useMemo
  • Funksiya kerak → useCallback

Qachon useCallback kerak?

useCallback ham xarajat. Har joyga qo'yish shart emas.

Kerak bo'lgan holat:

// ✅ React.memo bilan optimizatsiya qilingan bolaga berilganda
const Bola = React.memo(({ onClick }) => {
  return <button onClick={onClick}>Bosing</button>;
});

function Ota() {
  const bosish = useCallback(() => {
    // ...
  }, []);

  return <Bola onClick={bosish} />;
}
// ✅ useEffect dependency da funksiya bo'lganda
function Komponent({ id }) {
  const olish = useCallback(async () => {
    const data = await fetch(`/api/${id}`);
    return data.json();
  }, [id]);

  useEffect(() => {
    olish().then(setData);
  }, [olish]); // olish dependency da — useCallback bo'lmasa cheksiz loop
}

Kerak bo'lmagan holat:

// ❌ Oddiy event handler — useCallback shart emas
const bosish = useCallback(() => {
  setSon(s => s + 1);
}, []);

// ✅ Shunchaki yozing
function bosish() {
  setSon(s => s + 1);
}

Umumiy rasm

Optimizatsiya vositalari:

React.memo    → komponentni keshlaydi (props o'zgarmasa qayta chizilmaydi)
useMemo       → hisoblash natijasini keshlaydi
useCallback   → funksiyani keshlaydi

Ular birgalikda ishlaydi:
  useCallback → funksiya barqaror
  React.memo  → funksiya o'zgarmadi → bola qayta chizilmadi

Xulosa

useCallback(() => funksiya, [dependency])
                                │
                                └── bular o'zgarmasa — xuddi shu funksiya
  • Har render da funksiya qayta yaratiladi — bu normal
  • React.memo bilan optimizatsiya qilingan bolaga berilganda → useCallback
  • useEffect dependency da funksiya bo'lganda → useCallback
  • Oddiy event handler uchun → shart emas

Keyingi dars

17-dars: useContext — Context nima, Provider, Consumer