React ilə E-commerce: Azərbaycan Bazarı üçün Komponent Arxitekturası
Tap.az, Umico və ya öz e-commerce layihən üçün scalable React komponent arxitekturası necə qurulur? Real kod, real struktur, real təcrübə.
React ilə E-commerce: Azərbaycan Bazarı üçün Komponent Arxitekturası
Salam, developer dostlar! Bu gün Azərbaycan e-commerce bazarı üçün React komponent arxitekturası haqqında danışacağıq — konkret, praktiki və copy-paste edə biləcəyiniz kod nümunələri ilə.
Bakıda hazırda orta və böyük şirkətlərdə (Umico, ABB, Bravo, Kontakt Home) frontend developer tələbi ciddi artıb. LinkedIn-də "React developer Baku" axtarışı etsəniz, 60+ aktiv vakansiya görəcəksiniz. Maaş diapazonu Junior üçün 800-1200 AZN, Middle üçün 1500-2500 AZN, Senior üçün isə 3000-5000+ AZN civarındadır. Bu vakansiyaların əksəriyyətində e-commerce təcrübəsi üstünlük kimi qeyd olunur.
Bəs niyə komponent arxitekturası bu qədər vacibdir?
Problem: Spaghetti Komponentlər
Təsəvvür edin, Kontakt Home kimi bir elektronika mağazası üçün sayt yazırsınız. Əvvəlcə bir ProductPage.jsx faylı yaradırsınız — 500 sətir. Sonra ora filter əlavə edirsiniz — 800 sətir. Sonra AZN/USD valyuta çevirici, karqo kalkulyatoru... və artıq 1500 sətirlik bir monster var əlinizdə.
Bu yanaşma ilə:
- Yeni developer komandaya qoşulanda 2 həftə fayl oxuyur
- Bir bug fix 5 yeni bug yaradır
- Test yazmaq mümkünsüz olur
Həll: Atomic Design + Feature-Based Struktur
Azərbaycan e-commerce layihəsi üçün ən optimal yanaşma Atomic Design prinsipi ilə Feature-Based folder strukturunun birləşməsidir.
Folder Strukturu
src/
├── components/
│ ├── atoms/
│ │ ├── Button/
│ │ ├── PriceTag/
│ │ ├── Badge/
│ │ └── CurrencyDisplay/
│ ├── molecules/
│ │ ├── ProductCard/
│ │ ├── SearchBar/
│ │ ├── CartItem/
│ │ └── FilterChip/
│ ├── organisms/
│ │ ├── ProductGrid/
│ │ ├── Header/
│ │ ├── CartSidebar/
│ │ └── FilterPanel/
│ └── templates/
│ ├── CatalogLayout/
│ └── CheckoutLayout/
├── features/
│ ├── catalog/
│ ├── cart/
│ ├── checkout/
│ └── auth/
├── hooks/
│ ├── useCart.js
│ ├── useCurrency.js
│ └── useLocalStorage.js
├── utils/
│ ├── formatAZN.js
│ └── transliterate.js
└── constants/
└── regions.js
Bu struktur 50+ komponentlik layihədə belə naviqasiyanı rahat edir.
Real Kod: AZN Qiymət Komponenti
Azərbaycan e-commerce saytının ən əsas atom komponenti — qiymət göstəricisi. Gəlin PriceTag komponentini yazaq:
jsx// src/components/atoms/PriceTag/PriceTag.jsx import { memo } from 'react'; import { formatAZN } from '../../../utils/formatAZN'; import styles from './PriceTag.module.css'; const PriceTag = memo(({ price, oldPrice, size = 'md', showManat = true }) => { const hasDiscount = oldPrice && oldPrice > price; const discountPercent = hasDiscount ? Math.round(((oldPrice - price) / oldPrice) * 100) : 0; return ( <div className={`${styles.wrapper} ${styles[size]}`}> {hasDiscount && ( <span className={styles.oldPrice}> {formatAZN(oldPrice)} </span> )} <span className={styles.currentPrice}> {formatAZN(price)} {showManat && <span className={styles.currency}> ₼</span>} </span> {hasDiscount && ( <span className={styles.discount}>-{discountPercent}%</span> )} </div> ); }); PriceTag.displayName = 'PriceTag'; export default PriceTag;
js// src/utils/formatAZN.js export const formatAZN = (amount) => { return new Intl.NumberFormat('az-AZ', { minimumFractionDigits: 2, maximumFractionDigits: 2, }).format(amount); }; // formatAZN(1499.9) → "1 499,90"
Bu kiçik atom komponenti layihənin hər yerində istifadə olunacaq — ProductCard, CartItem, OrderSummary hamısı bunu çağırır.
Molecule Səviyyəsi: ProductCard
İndi atom komponentləri birləşdirərək ProductCard molecule yaradaq:
jsx// src/components/molecules/ProductCard/ProductCard.jsx import PriceTag from '../../atoms/PriceTag/PriceTag'; import Badge from '../../atoms/Badge/Badge'; import Button from '../../atoms/Button/Button'; import { useCart } from '../../../hooks/useCart'; import styles from './ProductCard.module.css'; const ProductCard = ({ product }) => { const { addToCart, isInCart } = useCart(); const { id, name, image, price, oldPrice, inStock, isNew } = product; return ( <article className={styles.card}> <div className={styles.imageWrapper}> <img src={image} alt={name} loading="lazy" /> {isNew && <Badge variant="new">Yeni</Badge>} {!inStock && <Badge variant="outOfStock">Stokda yoxdur</Badge>} </div> <div className={styles.info}> <h3 className={styles.name}>{name}</h3> <PriceTag price={price} oldPrice={oldPrice} /> </div> <Button variant={isInCart(id) ? 'secondary' : 'primary'} onClick={() => addToCart(product)} disabled={!inStock} fullWidth > {isInCart(id) ? 'Səbətdədir ✓' : 'Səbətə at'} </Button> </article> ); }; export default ProductCard;
Diqqət edin: ProductCard heç bir business logic saxlamır. Səbət məntiqi useCart hook-unda, qiymət formatlaması PriceTag-da, vizual badge-lər Badge-dadır. Hər şey öz yerində.
Custom Hook: useCart
Business logic-i komponentlərdən ayırmaq üçün custom hook-lar istifadə edirik:
jsx// src/hooks/useCart.js import { useCallback, useMemo } from 'react'; import { useLocalStorage } from './useLocalStorage'; export const useCart = () => { const [items, setItems] = useLocalStorage('cart', []); const addToCart = useCallback((product) => { setItems((prev) => { const exists = prev.find((item) => item.id === product.id); if (exists) { return prev.map((item) => item.id === product.id ? { ...item, quantity: item.quantity + 1 } : item ); } return [...prev, { ...product, quantity: 1 }]; }); }, [setItems]); const isInCart = useCallback( (id) => items.some((item) => item.id === id), [items] ); const total = useMemo( () => items.reduce((sum, item) => sum + item.price * item.quantity, 0), [items] ); return { items, addToCart, isInCart, total, itemCount: items.length }; };
Bu hook localStorage ilə işləyir, yəni istifadəçi səhifəni yeniləsə belə səbət itmir. Azərbaycan istifadəçiləri üçün bu kritik feature-dur — internet bağlantısı kəsiləndə data itməməlidir.
Azərbaycana Xas Nüanslar
E-commerce layihəsində Azərbaycan kontekstini nəzərə almaq lazımdır:
- Valyuta: Həmişə AZN (₼) göstərin, lazım gələrsə USD çevirmə əlavə edin
- Ünvan sistemi: Bakı rayonları (Nəsimi, Yasamal, Binəqədi...) üçün ayrıca
RegionSelectorkomponenti yazın - Ödəniş metodları: Hər layihədə mütləq "Qapıda ödəniş" seçimi olmalıdır — Azərbaycanda alıcıların 60%-dən çoxu bunu seçir
- Dil dəstəyi: AZ/RU/EN — ən azı bu üç dil.
react-i18nextistifadə edin - Telefon formatı: +994 XX YYY YY YY formatında input mask lazımdır
js// src/constants/regions.js export const BAKU_REGIONS = [ { id: 'nasimi', label: 'Nəsimi', deliveryFee: 3.00 }, { id: 'yasamal', label: 'Yasamal', deliveryFee: 3.00 }, { id: 'sabunchu', label: 'Sabunçu', deliveryFee: 5.00 }, { id: 'khirdalan', label: 'Xırdalan', deliveryFee: 7.00 }, // ... ];
Performance: Nəyə Diqqət Etməli?
Umico kimi saytda minlərlə məhsul var. Performance üçün:
- React.memo —
ProductCardkimi tez-tez render olunan komponentlər üçün - Virtualization —
react-windowilə uzun məhsul siyahıları üçün (1000+ item) - Code Splitting — Checkout səhifəsi lazy load olsun:
React.lazy(() => import('./features/checkout')) - Image optimization — WebP format,
loading="lazy", responsive srcSet
Bu optimizasiyalar First Contentful Paint-i 40-60% yaxşılaşdıra bilər.
Nəticə
Yaxşı komponent arxitekturası:
- Yeni developerin onboarding müddətini 2 həftədən 2-3 günə endirir
- Bug fix vaxtını ortalama 3x azaldır
- Feature əlavə etməyi asanlaşdırır
Əgər portfolionuzda belə strukturlaşdırılmış bir e-commerce layihəsi varsa, Bakıdakı şirkətlər (Umico, Tap.az, ABB, Bravo online) bunu mütləq qiymətləndirəcək. GitHub-da public repo kimi paylaşın, README-də arxitektura diaqramı çəkin.
Sualınız varsa LinkedIn-də və ya kommentlərdə yazın. Növbəti məqalədə bu arxitekturanın üzərinə state management (Zustand vs Redux Toolkit) əlavə edəcəyik.
Kod yazmağa davam! 🚀
Oxşar məqalələr
React-da Performans: useMemo və useCallback — Nə Vaxt Lazımdır?
useMemo və useCallback hər yerə yazmaq reflex olub? Gəl birlikdə anlayaq: bu hook-lar nə vaxt həqiqətən lazımdır, nə vaxt isə əksinə — zərərdir.
React Query ilə Server State: useState-dən Qurtuluş Yolu
Hələ də API datanı useState + useEffect ilə idarə edirsən? React Query ilə server state-i necə peşəkar səviyyədə idarə etməyi öyrən.
React Server Components — Nə Vaxt İstifadə Etməli, Nə Vaxt Yox?
RSC hər yerə lazım deyil. Bu məqalədə real kod nümunələri ilə Server Components-in nə vaxt performans artırdığını, nə vaxt isə əngəl olduğunu izah edirik.