React

useEffect va yon effektlar

Ba'zan komponent shunchaki ekranga chizishdan tashqari ish bajarishi kerak: serverdan ma'lumot yuklash, timer o'rnatish, hujjat sarlavhasini o'zgartirish. Bunday amallar yon effektlar (side effects) deb ataladi. Ular uchun React'da useEffect hook mavjud.

Yon effekt (side effect) nima?

React komponentining asosiy vazifasi โ€” props va state asosida JSX qaytarish (ya'ni ekranni chizish). Bu โ€” "sof" hisoblash. Lekin ba'zan komponent tashqi dunyo bilan aloqa qilishi kerak. Ana shunday amallar yon effekt deyiladi:

Bunday amallarni to'g'ridan-to'g'ri komponent tanasiga yozib bo'lmaydi โ€” chunki komponent har render'da qayta ishga tushadi, natijada effekt behuda ko'p marta bajarilib qolardi. Buning uchun useEffect ishlatiladi.

useEffect asoslari

useEffect ni ham React'dan import qilamiz. U ikki argument oladi: funksiya (effekt) va dependency array (bog'liqliklar massivi):

import { useEffect } from "react";

useEffect(() => {
  // yon effekt kodi shu yerda
}, []);

Effekt funksiyasi komponent ekranga chizilgandan keyin ishga tushadi. Sodda misol โ€” hujjat sarlavhasini hisoblagich qiymatiga qarab yangilash:

import { useState, useEffect } from "react";

function Sarlavha() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    document.title = "Bosildi: " + count;
  }, [count]);

  return <button onClick={() => setCount(count + 1)}>+1</button>;
}

Bu yerda har safar count o'zgarganda, effekt ishga tushib, brauzer tabidagi sarlavhani yangilaydi.

Dependency array โ€” bog'liqliklar massivi

Ikkinchi argument โ€” dependency array โ€” effekt qachon qayta ishga tushishini boshqaradi. Uchta asosiy holat bor:

// 1) Har render'dan keyin ishga tushadi (massiv YO'Q)
useEffect(() => {
  console.log("har safar");
});

// 2) Faqat BIR MARTA โ€” komponent birinchi paydo bo'lganda
useEffect(() => {
  console.log("faqat bir marta");
}, []);

// 3) Faqat count o'zgarganda ishga tushadi
useEffect(() => {
  console.log("count o'zgardi");
}, [count]);

Buni jadval sifatida esda tuting:

Effekt ichida ishlatilgan har qanday state yoki prop dependency massivida ko'rsatilishi kerak. Aks holda effekt eski qiymatlar bilan ishlab, chalkash xatolar yuzaga keladi. Bo'sh massiv [] berishdan oldin, effekt tashqi qiymatlarga bog'liq emasligiga ishonch hosil qiling.

fetch bilan ma'lumot yuklash

useEffectning eng ko'p uchraydigan qo'llanilishi โ€” komponent paydo bo'lganda serverdan ma'lumot yuklash. Buning uchun bo'sh massiv [] ishlatamiz (bir marta yuklansin) va natijani state'ga saqlaymiz:

import { useState, useEffect } from "react";

function Foydalanuvchilar() {
  const [users, setUsers] = useState([]);

  useEffect(() => {
    fetch("https://jsonplaceholder.typicode.com/users")
      .then(res => res.json())
      .then(data => setUsers(data));
  }, []);

  return (
    <ul>
      {users.map(u => <li key={u.id}>{u.name}</li>)}
    </ul>
  );
}

Jarayon shunday kechadi: komponent birinchi bor chiziladi (users bo'sh massiv), effekt ishga tushib fetch qiladi, ma'lumot kelgach setUsers state'ni yangilaydi, React qayta render qiladi va ro'yxat ekranda paydo bo'ladi.

Amalda ko'pincha yuklanish holati (loading) va xatolikni ham hisobga olamiz:

function Foydalanuvchilar() {
  const [users, setUsers] = useState([]);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    fetch("https://jsonplaceholder.typicode.com/users")
      .then(res => res.json())
      .then(data => {
        setUsers(data);
        setLoading(false);
      });
  }, []);

  if (loading) return <p>Yuklanmoqda...</p>;

  return <ul>{users.map(u => <li key={u.id}>{u.name}</li>)}</ul>;
}
Effekt funksiyasini async qilib bo'lmaydi. Buning o'rniga effekt ichida alohida async funksiya yozib, uni chaqirasiz, yoki yuqoridagidek .then() ishlatasiz.

Cleanup funksiyasi โ€” tozalash

Ba'zi effektlar "o'zidan keyin tozalash"ni talab qiladi. Masalan, agar siz timer o'rnatgan yoki hodisaga obuna bo'lgan bo'lsangiz, komponent yo'qolganda ularni bekor qilish kerak โ€” aks holda xotira sizib chiqadi (memory leak). Buning uchun effekt funksiyasidan tozalash funksiyasini qaytaramiz:

useEffect(() => {
  const id = setInterval(() => {
    console.log("har soniyada");
  }, 1000);

  // cleanup: komponent yo'qolganda interval to'xtatiladi
  return () => {
    clearInterval(id);
  };
}, []);

Bu yerda qaytarilgan funksiya โ€” cleanup (tozalash) funksiyasi. React uni ikki holatda chaqiradi:

Timer bilan real misol โ€” soniyalarni sanovchi:

function Soat() {
  const [soniya, setSoniya] = useState(0);

  useEffect(() => {
    const id = setInterval(() => {
      setSoniya(prev => prev + 1);
    }, 1000);
    return () => clearInterval(id);
  }, []);

  return <p>O'tgan vaqt: {soniya} soniya</p>;
}
Agar cleanup'ni unutsangiz, har render'da yangi interval ochilib, eskisi to'xtamay qoladi โ€” natijada bir necha timer parallel ishlab ketadi. Doim tozalashni yodda tuting.

Effekt qachon va qanday tartibda ishlaydi

Effektlarning ish tartibini yaxlit ko'rib chiqamiz. Komponent hayoti davomida:

  1. Komponent birinchi bor chiziladi (mount) โ†’ effekt ishga tushadi;
  2. Dependency o'zgaradi โ†’ avval eski effekt cleanupi chaqiriladi โ†’ so'ng yangi effekt ishlaydi;
  3. Komponent yo'qoladi (unmount) โ†’ oxirgi cleanup chaqiriladi.

Muhim: effekt har doim ekran chizilgandan keyin ishlaydi. Ya'ni foydalanuvchi avval interfeysni ko'radi, so'ng effekt (masalan, ma'lumot yuklash) ishga tushadi. Bu interfeysni bloklamaslik uchun shunday qilingan.

Xulosa