useContext — global state, prop drilling muammosini hal qilish
Global state nima?
Ba'zi ma'lumotlar butun ilova bo'ylab kerak bo'ladi. Masalan:
- Foydalanuvchi — kim login qilgan, ismi, roli
- Tema — qorang'i yoki yorug'
- Til — o'zbek, rus, ingliz
- Savat — nechta mahsulot qo'shilgan
Bu ma'lumotlarni har bir komponentga props orqali uzatish — prop drilling. Oldingi darsda Context ni o'rgandik. Endi uni real loyihada qanday ishlatishni ko'ramiz.
Savat — amaliy misol
E-commerce saytda savat — klassik global state misoli. Mahsulot sahifasida "Savatga qo'shish" tugmasi bor. Navbar da savatdagi mahsulotlar soni ko'rsatiladi. Savat sahifasida ro'yxat ko'rsatiladi.
Bu uchta komponent bir-biridan uzoqda. Props bilan bog'lash — prop drilling. Context bilan — har biri to'g'ridan-to'g'ri oladi.
// SavatContext.jsx
import { createContext, useContext, useState } from 'react';
const SavatContext = createContext();
export function SavatProvider({ children }) {
const [mahsulotlar, setMahsulotlar] = useState([]);
// Savatga qo'shish — agar allaqachon bor bo'lsa, sonini oshir
function qoshish(mahsulot) {
setMahsulotlar(prev => {
const bor = prev.find(m => m.id === mahsulot.id);
if (bor) {
return prev.map(m =>
m.id === mahsulot.id ? { ...m, son: m.son + 1 } : m
);
}
return [...prev, { ...mahsulot, son: 1 }];
});
}
function ochirish(id) {
setMahsulotlar(prev => prev.filter(m => m.id !== id));
}
// Jami narx — har render da hisoblanadi
const jami = mahsulotlar.reduce((sum, m) => sum + m.narx * m.son, 0);
return (
<SavatContext.Provider value={{ mahsulotlar, qoshish, ochirish, jami }}>
{children}
</SavatContext.Provider>
);
}
export function useSavat() {
const context = useContext(SavatContext);
if (!context) throw new Error('useSavat SavatProvider ichida ishlatilishi kerak');
return context;
}
Endi istalgan komponentda useSavat() chaqiriladi — props shart emas:
// Navbar.jsx — savatdagi mahsulotlar sonini ko'rsatish
function Navbar() {
const { mahsulotlar } = useSavat();
return (
<nav>
<span>Do'kon</span>
<span>🛒 {mahsulotlar.length}</span>
</nav>
);
}
// MahsulotKarta.jsx — savatga qo'shish
function MahsulotKarta({ mahsulot }) {
const { qoshish } = useSavat();
return (
<div>
<h3>{mahsulot.nomi}</h3>
<p>{mahsulot.narx.toLocaleString()} so'm</p>
<button onClick={() => qoshish(mahsulot)}>
Savatga qo'shish
</button>
</div>
);
}
// SavatSahifa.jsx — ro'yxat va jami
function SavatSahifa() {
const { mahsulotlar, ochirish, jami } = useSavat();
if (mahsulotlar.length === 0) return <p>Savat bo'sh</p>;
return (
<div>
{mahsulotlar.map(m => (
<div key={m.id}>
<span>{m.nomi} × {m.son}</span>
<button onClick={() => ochirish(m.id)}>O'chirish</button>
</div>
))}
<strong>Jami: {jami.toLocaleString()} so'm</strong>
</div>
);
}
MahsulotKarta da "Savatga qo'shish" bosilganda — Navbar dagi son avtomatik yangilanadi. Ular bir-birini bilmaydi, lekin bir xil Context dan foydalanadi.
Bir nechta Provider
Real loyihada bir nechta Context bo'ladi. Ularni App da ketma-ket o'rasiz:
function App() {
return (
<TemaProvider>
<UserProvider>
<SavatProvider>
<Sahifalar />
</SavatProvider>
</UserProvider>
</TemaProvider>
);
}
TemaProvider
└── UserProvider
└── SavatProvider
└── istalgan komponent
useTema() → tema
useUser() → foydalanuvchi
useSavat() → savat
Har bir komponent faqat kerakli narsani oladi. useTema() chaqirgan komponent faqat tema o'zgarganda qayta chiziladi — savat o'zgarganda emas.
Context vs Zustand
Context — React ning o'z vositasi, qo'shimcha kutubxona kerak emas. Lekin cheklovi bor:
Context:
✅ Oddiy, o'rnatish shart emas
✅ Kichik-o'rta loyiha uchun yetarli
❌ Tez-tez o'zgaradigan ma'lumot uchun sekin
(har o'zgarishda barcha consumer qayta chiziladi)
Zustand:
✅ Tez-tez o'zgaradigan ma'lumot uchun optimallashtirilgan
✅ Kichik va sodda API
❌ Qo'shimcha kutubxona
Foydalanuvchi ma'lumoti, tema, til — sekin o'zgaradi, Context yetarli. Real-time yangilanadigan katta state — Zustand yaxshiroq.
Xulosa
Context — global state uchun. Bir marta Provider bilan o'rasiz, istalgan joyda custom hook bilan olasiz.
Har bir Context uchun:
- Alohida fayl
ProviderkomponentiuseXxx()custom hook — qulay interfeys va xato tekshiruvi
Keyingi dars
19-dars: useReducer — nima, useState dan farqi, qachon ishlatiladi