Kirish
React.js bugungi kunda eng mashhur frontend kutubxonalardan biri. Lekin uni to'g'ri ishlatmasangiz, ilovangiz sekin ishlashi va kod boshqarilmaydigan holatga kelishi mumkin. Ushbu maqolada React bilan professional darajada ishlash uchun eng yaxshi amaliyotlarni ko'rib chiqamiz.
1. Komponent Strukturasi
Kichik va qayta ishlatiladigan komponentlar yarating
Har bir komponent faqat bitta vazifani bajarishi kerak (Single Responsibility Principle).// ❌ Yomon - katta va murakkab komponent
function UserDashboard() {
return (
<div>
<header>...</header>
<nav>...</nav>
<main>...</main>
<footer>...</footer>
</div>
);
}
// ✅ Yaxshi - kichik, qayta ishlatiladigan komponentlar
function UserDashboard() {
return (
<div>
<Header />
<Navigation />
<MainContent />
<Footer />
</div>
);
}
Komponentlarni to'g'ri nomlash
// ❌ Yomon
function btn() { }
function usercard() { }
// ✅ Yaxshi - PascalCase
function Button() { }
function UserCard() { }
2. State Boshqaruvi
State'ni minimal darajada saqlang
F
aqat zarur bo'lgan ma'lumotlarni state'da saqlang. Hisoblangan qiymatlarni state'ga qo'ymang.// ❌ Yomon - ortiqcha state
const [users, setUsers] = useState([]);
const [userCount, setUserCount] = useState(0);
useEffect(() => {
setUserCount(users.length);
}, [users]);
// ✅ Yaxshi - hisoblangan qiymat
const [users, setUsers] = useState([]);
const userCount = users.length;
Ob'ektlarni immutable yangilang
// ❌ Yomon - to'g'ridan-to'g'ri o'zgartirish
const updateUser = () => {
user.name = "Yangi ism";
setUser(user);
};
// ✅ Yaxshi - yangi ob'ekt yaratish
const updateUser = () => {
setUser({
...user,
name: "Yangi ism"
});
};
3. Performance Optimization
React.memo() - komponentni memoize qilish
Agar komponent props o'zgarmasa, qayta render qilinmasligi uchun React.memo() ishlatamiz.
import { memo } from 'react';
const UserCard = memo(({ user }) => {
console.log('UserCard render');
return (
<div>
<h3>{user.name}</h3>
<p>{user.email}</p>
</div>
);
});
export default UserCard;
useMemo() - qimmat hisob-kitoblarni cache qilish
import { useMemo } from 'react';
function ProductList({ products, filter }) {
// Faqat products yoki filter o'zgarganda qayta hisoblaydi
const filteredProducts = useMemo(() => {
console.log('Filtering...');
return products.filter(p => p.category === filter);
}, [products, filter]);
return (
<div>
{filteredProducts.map(p => (
<ProductCard key={p.id} product={p} />
))}
</div>
);
}
useCallback() - funksiyalarni cache qilish
import { useCallback } from 'react';
function Parent() {
const [count, setCount] = useState(0);
// handleClick faqat count o'zgargandagina qayta yaratiladi
const handleClick = useCallback(() => {
console.log('Clicked:', count);
}, [count]);
return <Child onClick={handleClick} />;
}
⚠️ Muhim
useMemo va useCallback har doim ham kerak emas! Faqat performans muammosi bo'lganda ishlating. Ortiqcha ishlatish kod murakkablashtirib yuboradi.
4. Custom Hooks
Takrorlanuvchi logikani custom hook'larga ajrating.
Fetch uchun custom hook
// hooks/useFetch.js
import { useState, useEffect } from 'react';
function useFetch(url) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
const fetchData = async () => {
try {
const response = await fetch(url);
const json = await response.json();
setData(json);
} catch (err) {
setError(err);
} finally {
setLoading(false);
}
};
fetchData();
}, [url]);
return { data, loading, error };
}
// Ishlatish
function Users() {
const { data, loading, error } = useFetch('/api/users');
if (loading) return <p>Yuklanmoqda...</p>;
if (error) return <p>Xato: {error.message}</p>;
return (
<div>
{data.map(user => (
<UserCard key={user.id} user={user} />
))}
</div>
);
}
Form uchun custom hook
// hooks/useForm.js
import { useState } from 'react';
function useForm(initialValues) {
const [values, setValues] = useState(initialValues);
const handleChange = (e) => {
setValues({
...values,
[e.target.name]: e.target.value
});
};
const reset = () => {
setValues(initialValues);
};
return { values, handleChange, reset };
}
// Ishlatish
function LoginForm() {
const { values, handleChange, reset } = useForm({
email: '',
password: ''
});
const handleSubmit = (e) => {
e.preventDefault();
console.log(values);
reset();
};
return (
<form onSubmit={handleSubmit}>
<input
name="email"
value={values.email}
onChange={handleChange}
/>
<input
name="password"
type="password"
value={values.password}
onChange={handleChange}
/>
<button type="submit">Kirish</button>
</form>
);
}
5. Code Splitting va Lazy Loading
Katta ilovalarni kichik qismlarga bo'lib, zarur bo'lganda yuklaymiz.
import { lazy, Suspense } from 'react';
// Lazy loading
const Dashboard = lazy(() => import('./pages/Dashboard'));
const Profile = lazy(() => import('./pages/Profile'));
const Settings = lazy(() => import('./pages/Settings'));
function App() {
return (
<Suspense fallback={<div>Yuklanmoqda...</div>}>
<Routes>
<Route path="/dashboard" element={<Dashboard />} />
<Route path="/profile" element={<Profile />} />
<Route path="/settings" element={<Settings />} />
</Routes>
</Suspense>
);
}
6. Error Boundaries
Xatolarni tutish va foydalanuvchiga chiroyli ko'rinishda ko'rsatish.
import { Component } from 'react';
class ErrorBoundary extends Component {
state = { hasError: false };
static getDerivedStateFromError(error) {
return { hasError: true };
}
componentDidCatch(error, errorInfo) {
console.error('Error:', error, errorInfo);
}
render() {
if (this.state.hasError) {
return (
<div>
<h2>Xatolik yuz berdi</h2>
<p>Iltimos, sahifani yangilang</p>
</div>
);
}
return this.props.children;
}
}
// Ishlatish
function App() {
return (
<ErrorBoundary>
<MyApp />
</ErrorBoundary>
);
}
7. Props Drilling Muammosini Hal Qilish
Context API
import { createContext, useContext, useState } from 'react';
// Context yaratish
const ThemeContext = createContext();
// Provider
function ThemeProvider({ children }) {
const [theme, setTheme] = useState('light');
return (
<ThemeContext.Provider value={{ theme, setTheme }}>
{children}
</ThemeContext.Provider>
);
}
// Custom hook
function useTheme() {
return useContext(ThemeContext);
}
// Ishlatish
function Button() {
const { theme, setTheme } = useTheme();
return (
<button
className={theme}
onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}
>
Theme: {theme}
</button>
);
}
8. TypeScript bilan ishlash
TypeScript kodni xavfsizroq va tushunarli qiladi.
// Props uchun interface
interface UserCardProps {
user: {
id: number;
name: string;
email: string;
role?: 'admin' | 'user';
};
onDelete?: (id: number) => void;
}
const UserCard: React.FC<UserCardProps> = ({ user, onDelete }) => {
return (
<div className="user-card">
<h3>{user.name}</h3>
<p>{user.email}</p>
{user.role && <span>{user.role}</span>}
{onDelete && (
<button onClick={() => onDelete(user.id)}>
O'chirish
</button>
)}
</div>
);
};
9. Testing
Komponentlarni test qilish kod sifatini oshiradi.
import { render, screen, fireEvent } from '@testing-library/react';
import Counter from './Counter';
test('counter increment ishlaydi', () => {
render(<Counter />);
const button = screen.getByText('Increment');
const count = screen.getByText('Count: 0');
fireEvent.click(button);
expect(count).toHaveTextContent('Count: 1');
});
✅ Best Practices Checklist
- Komponentlarni kichik va sodda qiling
- State'ni minimal saqlang
- Props'ni destructure qiling
- Key prop'ni to'g'ri ishlating
- useEffect dependency array'ini unutmang
- Custom hook'lar yarating
- Code splitting qiling
- TypeScript ishlating
- Test yozing
- ESLint va Prettier o'rnating
Xulosa
React.js bilan professional darajada ishlash uchun bu amaliyotlarni doimo yodda tuting. Kod sifati va performans bir-biriga bog'liq - yaxshi yozilgan kod tez ishlaydi va boshqarilishi oson.
Keyingi maqolalarda ko'ramiz:
- React state management (Redux, Zustand)
- React Query va server state
- React Native bilan mobile development
- Next.js va server-side rendering