React useEffect: yon ta'sirlar
Shu paytgacha yozgan kodingiz bitta ish qilardi: ma’lumotdan ko’rinish
hosil qilish. Lekin ilovaga taymer, sahifa sarlavhasini o’zgartirish yoki
serverdan ma’lumot olish kerak bo’lsa, bu ishlar chizish jarayoniga
sig’maydi. useEffect shunday ishlar uchun.
Yon ta’sir nima
Farqni ko’ring:
| Ko’rinish hosil qilish | Yon ta’sir |
|---|---|
tasks dan <li> yasash |
Serverdan tasks olish |
| Sanoqni ekranga chiqarish | document.title ni o’zgartirish |
| Sinf nomini hisoblash | setInterval o’rnatish |
Yon ta’sirni komponent tanasiga yozib bo’lmaydi:
// ❌ Shunday qilmang
function Counter() {
const [count, setCount] = useState(0);
document.title = `Bosilgan: ${count}`; // chizish paytida
return <button onClick={() => setCount(count + 1)}>{count}</button>;
}
Komponent funksiyasi ko’p marta va kutilmagan paytlarda chaqirilishi mumkin. U faqat JSX hisoblab qaytarishi kerak — boshqa hech nima qilmasligi kerak.
Birinchi effekt
To’g’ri yozilishi:
import { useState, useEffect } from 'react';
function Counter() {
const [count, setCount] = useState(0);
useEffect(() => {
document.title = `Bosilgan: ${count}`;
}, [count]);
return (
<button type="button" onClick={() => setCount(count + 1)}>
Bosilgan: {count}
</button>
);
}
export default Counter;
Tugmani bosing — brauzer yorlig’idagi yozuv ham o’zgaradi.
useEffect ikki argument oladi:
- Funksiya — bajariladigan ish;
- Bog’liqliklar massivi — qachon bajarilishini belgilaydi.
Effekt komponent chizilib, DOM yangilangandan keyin ishlaydi. Shuning uchun u chizishni sekinlashtirmaydi.
Bog’liqliklar massivi
Ikkinchi argument effekt qachon qayta ishlashini hal qiladi. Uch variant bor va farqi katta:
// 1. Har chizishda
useEffect(() => {
console.log("Har safar");
});
// 2. Faqat bir marta — komponent paydo bo'lganda
useEffect(() => {
console.log("Bir marta");
}, []);
// 3. count o'zgarganda
useEffect(() => {
console.log("count o'zgardi:", count);
}, [count]);
| Ikkinchi argument | Qachon ishlaydi |
|---|---|
| yo’q | Har chizishdan keyin |
[] |
Faqat birinchi chizishdan keyin |
[count] |
Birinchi chizishda va count o’zgarganda |
[a, b] |
Birinchi chizishda va a yoki b o’zgarganda |
React bog’liqliklarni oldingi qiymatlar bilan solishtiradi. Bittasi ham o’zgargan bo’lsa effekt qayta ishlaydi.
Tozalash funksiyasi
Ba’zi yon ta’sirlar orqasida iz qoldiradi: ishlab turgan taymer, ochiq obuna, qo’shilgan hodisa ishlovchisi. Ular to’xtatilmasa xotira sarflanadi va xatolar chiqadi.
Effekt funksiya qaytarsa, React uni tozalash uchun chaqiradi:
import { useState, useEffect } from 'react';
function Timer() {
const [seconds, setSeconds] = useState(0);
useEffect(() => {
const intervalId = setInterval(() => {
setSeconds((previous) => previous + 1);
}, 1000);
// Tozalash funksiyasi
return () => {
clearInterval(intervalId);
};
}, []);
return <p>O'tgan vaqt: {seconds} soniya</p>;
}
export default Timer;
Ekranda raqam har soniyada oshadi. Komponent ekrandan ketganda taymer to’xtatiladi.
Ikkinchi holat muhim. [count] bog’liqlikli effekt shunday ketma-ketlik
bilan ishlaydi:
count = 0 → effekt ishladi
count = 1 → tozalash (eski) → effekt (yangi)
count = 2 → tozalash (eski) → effekt (yangi)
Ya’ni yangi effekt boshlanishidan oldin eskisi yig’ishtiriladi. Shu tufayli ikkita taymer bir vaqtda ishlab qolmaydi.
Tozalash kerak bo’ladigan holatlar:
// Taymer
useEffect(() => {
const timeoutId = setTimeout(() => console.log("Vaqt tugadi"), 3000);
return () => clearTimeout(timeoutId);
}, []);
// Hodisaga obuna
useEffect(() => {
function handleResize() {
console.log("Yangi kenglik:", window.innerWidth);
}
window.addEventListener("resize", handleResize);
return () => window.removeEventListener("resize", handleResize);
}, []);
Ikkinchi misolda removeEventListener ga aynan o’sha funksiya
berilishi kerak. Shuning uchun handleResize effekt ichida e’lon
qilingan.
StrictMode: effekt ikki marta ishlaydi
Endi boshlovchilarni eng ko’p chalkashtiradigan joy. Konsolga yozuv chiqaradigan effekt yozasiz:
useEffect(() => {
console.log("Effekt ishladi");
}, []);
Bo’sh massiv — demak bir marta ishlashi kerak. Lekin konsolda:
Effekt ishladi
Effekt ishladi
Ikki marta. Kod to’g’ri, xato yo’q.
Tozalash to’g’ri yozilgan bo’lsa ketma-ketlik shunday ko’rinadi:
EFFEKT: obuna ochildi
TOZALASH: obuna yopildi
EFFEKT: obuna ochildi
Oxirida bitta ochiq obuna qoladi — to’g’ri natija.
Bog’liqlikni tushirib qoldirmang
Effekt ichida ishlatilgan har bir holat va props bog’liqliklar massivida bo’lishi kerak:
// ❌ userId o'zgarsa effekt qayta ishlamaydi
useEffect(() => {
console.log("Foydalanuvchi:", userId);
}, []);
// ✅ To'g'ri
useEffect(() => {
console.log("Foydalanuvchi:", userId);
}, [userId]);
Birinchi variant “eskirgan qiymat” muammosini beradi: effekt birinchi
userId ni yodda saqlab qoladi va yangilanishdan xabarsiz qolaveradi.
useEffect kerak bo’lmagan holatlar
Yangi o’rganayotganlar useEffect ni haddan tashqari ko’p ishlatadi.
Ikki keng tarqalgan ortiqcha holat:
1. Boshqa holatdan hisoblanadigan qiymat:
// ❌ Ortiqcha
const [tasks, setTasks] = useState([]);
const [activeCount, setActiveCount] = useState(0);
useEffect(() => {
setActiveCount(tasks.filter((task) => !task.isDone).length);
}, [tasks]);
// ✅ To'g'ridan-to'g'ri hisoblang
const activeCount = tasks.filter((task) => !task.isDone).length;
Ikkinchi variant qisqaroq, tezroq va nomuvofiqlik ehtimolini yo’qotadi.
2. Foydalanuvchi amaliga javob:
// ❌ Ortiqcha
useEffect(() => {
if (isSubmitted) {
sendToServer(form);
}
}, [isSubmitted]);
// ✅ Ishlovchi ichida
function handleSubmit(e) {
e.preventDefault();
sendToServer(form);
}
Qoida: amal foydalanuvchi harakatidan kelib chiqsa — ishlovchida.
useEffect esa komponent ekranda paydo bo’lgani yoki ma’lumot
o’zgargani uchun bajariladigan ishlar uchun.
Amaliy mashq
Counteryozing vauseEffectbilandocument.titleni yangilang — brauzer yorlig’idagi yozuv o’zgarishini kuzating.- Konsolga yozuv chiqaradigan
useEffect(() => {...}, [])yozing va ikki marta chiqqanini ko’ring. - Unga tozalash funksiyasi qo’shing va konsolda effekt → tozalash → effekt ketma-ketligini kuzating.
TimerkomponentinisetIntervalbilan yozing, tozalashdaclearIntervalbo’lsin.clearIntervalni vaqtincha o’chiring va raqam qanday tezlashib ketishini ko’ring —StrictModeikkita taymer ishga tushirgan. Keyin qaytaring.- Bog’liqliklar massivini butunlay o’chirib ko’ring va
npm run lintnima deyishini o’qing.
5-qadam StrictMode ning ma’nosini eng aniq ko’rsatadi: tozalashsiz
effekt darrov ikkilanadi va muammo ishlab chiqish paytidayoq ko’rinadi.
Qisqacha xulosa
- Yon ta’sir — ko’rinish hosil qilishdan tashqari ish: tarmoq, taymer, brauzer API. Komponent tanasiga yozilmaydi.
useEffect(fn, deps)effektni chizishdan keyin bajaradi.[]— bir marta,[dep]— bog’liqlik o’zgarganda, massivsiz — har chizishda.- Effekt qaytargan funksiya tozalash uchun: komponent ketganda va effekt qayta ishlashidan oldin chaqiriladi.
StrictModeda effekt ikki marta ishlaydi — bu xato emas, tozalashni tekshirish uchun ataylab qilingan va faqat ishlab chiqishda bo’ladi.- Effekt ichida ishlatilgan har qiymat bog’liqliklar massivida bo’lsin.
- Boshqa holatdan hisoblanadigan qiymat va foydalanuvchi amaliga javob
uchun
useEffectkerak emas.
Keyingi darsda serverdan ma’lumot yuklash —
useEffect va fetch birgalikda.