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:
- Server (API) dan ma'lumot yuklash (
fetch); - Timer yoki interval o'rnatish (
setInterval); - Hujjat sarlavhasini (
document.title) o'zgartirish; - Brauzer hodisalariga obuna bo'lish (
addEventListener); localStoragebilan ishlash.
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:
- Massiv umuman yo'q โ effekt har render'da ishlaydi (kamdan-kam kerak bo'ladi);
- Bo'sh massiv
[]โ effekt faqat bir marta, komponent birinchi ekranga chizilganda ishlaydi; - Qiymatli massiv
[a, b]โ effekt shu qiymatlardan biri o'zgarganda qayta ishlaydi.
[] 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>;
}
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:
- Komponent ekrandan yo'qolganda (unmount);
- Effekt qayta ishga tushishidan oldin (agar dependency o'zgargan bo'lsa) โ avvalgi effekt tozalanib, keyin yangisi ishlaydi.
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>;
}
Effekt qachon va qanday tartibda ishlaydi
Effektlarning ish tartibini yaxlit ko'rib chiqamiz. Komponent hayoti davomida:
- Komponent birinchi bor chiziladi (mount) โ effekt ishga tushadi;
- Dependency o'zgaradi โ avval eski effekt cleanupi chaqiriladi โ so'ng yangi effekt ishlaydi;
- 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
- Yon effekt โ komponentning tashqi dunyo bilan aloqasi (fetch, timer, DOM o'zgartirish, obuna);
useEffect(fn, deps)effektni ekran chizilgandan keyin ishga tushiradi;- Dependency array effekt qachon qayta ishlashini boshqaradi:
[]โ bir marta,[x]โxo'zgarganda, yo'q bo'lsa โ har render'da; - Ma'lumot yuklash uchun
fetchniuseEffect(..., [])ichida ishlatib, natijani state'ga saqlaymiz; - Effektdan qaytarilgan cleanup funksiyasi timer/obunalarni tozalaydi โ xotira sizishining oldini oladi;
- Effekt ichida ishlatilgan barcha state/prop'lar dependency massivida bo'lishi kerak.