useEffect — nima, qachon ishlaydi, dependency array
Muammo: render vaqtida qilish mumkin bo'lmagan ishlar
Ba'zi ishlar komponent chizilayotganda emas, chizilgandan keyin bajarilishi kerak:
- Server dan ma'lumot olish
document.titleni o'zgartirish- Timer o'rnatish
- Event listener qo'shish
Nima uchun render vaqtida emas? Render — bu JSX qaytarish. Bu vaqtda DOM hali tayyor emas. Server so'rovi render ni to'xtatib qo'yadi. Bunday "yon ta'sirlar" (side effects) render dan tashqarida bo'lishi kerak.
useEffect — aynan shu "render dan keyin ishlaydigan" joy.
useEffect qanday ishlatiladi?
import { useState, useEffect } from 'react';
function App() {
const [son, setSon] = useState(0);
useEffect(() => {
document.title = `Bosimlar: ${son}`;
});
return (
<div>
<p>{son}</p>
<button onClick={() => setSon(son + 1)}>+1</button>
</div>
);
}
Render bo'ldi → useEffect ishladi → document.title yangilandi
Lekin bu holda useEffect har bir render da ishlaydi. Ko'pincha bu kerak emas — faqat ma'lum narsa o'zgarganda ishlashi kerak.
Dependency array — qachon ishlashini boshqarish
useEffect ning ikkinchi argumenti — dependency array (bog'liqliklar massivi).
useEffect(() => {
// ish
}, [bog'liqliklar]);
Uch holat bor:
useEffect(() => { ... })
→ har bir render da ishlaydi
useEffect(() => { ... }, [])
→ faqat birinchi render da ishlaydi (mount)
useEffect(() => { ... }, [qiymat])
→ birinchi render da + qiymat o'zgarganda ishlaydi
Vizual tushuntirish
[] — bo'sh massiv:
Mount → ✅ ishlaydi
Re-render → ❌ ishlamaydi
─────────────────────────────
Foydalanish: server so'rovi, event listener
[qiymat] — qiymat bilan:
Mount → ✅ ishlaydi
qiymat o'zgardi → ✅ ishlaydi
boshqa state o'zgardi → ❌ ishlamaydi
─────────────────────────────
Foydalanish: qiymatga bog'liq so'rov, hisoblash
(yo'q) — massiv yo'q:
Har bir render → ✅ ishlaydi
─────────────────────────────
Kamdan-kam kerak bo'ladi
Amaliy misollar
Server dan ma'lumot olish
function UserRoyxati() {
const [users, setUsers] = useState([]);
const [yuklanmoqda, setYuklanmoqda] = useState(true);
useEffect(() => {
fetch('https://jsonplaceholder.typicode.com/users')
.then(r => r.json())
.then(data => {
setUsers(data);
setYuklanmoqda(false);
});
}, []); // [] — faqat bir marta, komponent paydo bo'lganda
if (yuklanmoqda) return <p>Yuklanmoqda...</p>;
return (
<ul>
{users.map(u => <li key={u.id}>{u.name}</li>)}
</ul>
);
}
Qiymatga bog'liq so'rov
function UserProfil({ userId }) {
const [user, setUser] = useState(null);
useEffect(() => {
fetch(`/api/users/${userId}`)
.then(r => r.json())
.then(setUser);
}, [userId]); // userId o'zgarganda qayta so'rov yuboradi
if (!user) return <p>Yuklanmoqda...</p>;
return <h2>{user.name}</h2>;
}
userId props o'zgarsa — masalan, boshqa foydalanuvchi profiliga o'tilsa — useEffect qayta ishlaydi va yangi ma'lumot oladi.
document.title
function Sahifa({ sarlavha }) {
useEffect(() => {
document.title = sarlavha;
}, [sarlavha]); // sarlavha o'zgarganda yangilanadi
return <h1>{sarlavha}</h1>;
}
Tez-tez uchraydigan xatolar
Dependency array ni unutish:
// ❌ Har render da ishlaydi — cheksiz loop xavfi
useEffect(() => {
fetch('/api/users').then(...);
});
// ✅ Faqat bir marta
useEffect(() => {
fetch('/api/users').then(...);
}, []);
Dependency array ni to'liq to'ldirmaslik:
function Komponent({ id }) {
useEffect(() => {
fetch(`/api/${id}`).then(...); // id ishlatilmoqda
}, []); // ❌ id dependency da yo'q!
// id o'zgarganda useEffect qayta ishlamaydi
}
// ✅ To'g'ri
useEffect(() => {
fetch(`/api/${id}`).then(...);
}, [id]);
💡 Qoida oddiy:
useEffectichida ishlatilgan har bir o'zgaruvchi dependency array da bo'lishi kerak. ESLintreact-hooks/exhaustive-depsqoidasi buni avtomatik tekshiradi.
useEffect ichida async funksiya:
// ❌ Xato — useEffect callback async bo'lmasligi kerak
useEffect(async () => {
const data = await fetch('/api/users');
});
// ✅ To'g'ri — ichida alohida async funksiya
useEffect(() => {
async function olish() {
const res = await fetch('/api/users');
const data = await res.json();
setUsers(data);
}
olish();
}, []);
Nima uchun? useEffect callback Promise qaytarmasligi kerak — u cleanup funksiya qaytarishi mumkin (keyingi darsda). async funksiya har doim Promise qaytaradi.
Xulosa
useEffect(() => {
// render dan keyin ishlaydigan kod
}, [bog'liqliklar]);
[] → faqat mount da (bir marta)
[a, b] → mount da + a yoki b o'zgarganda
(yo'q) → har render da
- Server so'rovlari, DOM o'zgartirishlar, timer —
useEffectichida - Dependency array ni to'g'ri to'ldiring — ishlatilgan har bir o'zgaruvchi
async/awaituchun ichida alohida funksiya yozing
Keyingi dars
11-dars: useEffect — cleanup funksiya, nima uchun kerak