Image va expo-image — mahalliy va tarmoqdagi rasmlar
Muammodan boshlaylik
Mahsulot katalogi: har bir kartada rasm. Vebda <img src="..."> yetarli. React Native da birinchi urinish:
<Image source={{ uri: 'https://picsum.photos/400' }} />
Ekranda — hech narsa. Rasm yuklandi, lekin ko'rinmayapti. Sababi — React Native da tarmoqdagi rasmning o'lchami noma'lum va u 0×0 chiziladi.
Image — asosiy komponent
Mahalliy rasm — require
import { Image } from 'react-native';
<Image source={require('@/assets/images/logo.png')} style={{ width: 120, height: 40 }} />
require— rasm ilova bilan birga yig'iladi (bundle)- O'lcham avtomatik ma'lum, lekin odatda baribir beriladi
- Yo'l — o'zgaruvchi bo'lishi mumkin emas:
require(`./${nom}.png`)ishlamaydi
Retina ekranlar uchun bir nechta o'lcham:
assets/images/logo.png ← 1x
assets/images/logo@2x.png ← 2x
assets/images/logo@3x.png ← 3x
require('.../logo.png') — React Native qurilmaga mosini o'zi tanlaydi.
Tarmoqdagi rasm — uri
<Image
source={{ uri: 'https://picsum.photos/400' }}
style={{ width: 200, height: 200, borderRadius: 12 }}
/>
O'lcham majburiy — width va height yoki flex/aspectRatio.
aspectRatio — kenglikka moslash
<Image
source={{ uri: mahsulot.rasm }}
style={{ width: '100%', aspectRatio: 4 / 3 }}
/>
Kenglik — konteynerga teng, balandlik — 4:3 nisbatda avtomatik. Kartochkalar uchun eng qulay usul.
resizeMode — rasm qanday sig'diriladi
| Qiymat | Natija |
|---|---|
cover |
To'ldiradi, ortiqchasi qirqiladi (standart) |
contain |
To'liq ko'rinadi, bo'sh joy qolishi mumkin |
stretch |
Cho'zib to'ldiradi — nisbat buziladi |
center |
Asl o'lchamda markazda |
<Image source={{ uri }} style={styles.rasm} resizeMode="cover" />
CSS dagi object-fit ning o'zi.
expo-image — tavsiya etiladigan yo'l
O'rnatilgan Image oddiy holatlar uchun yetarli. Real ilovada expo-image yaxshiroq:
npx expo install expo-image
import { Image } from 'expo-image';
const blurhash = 'L6PZfSi_.AyE_3t7t7R**0o#DgR4';
<Image
source={mahsulot.rasm}
style={{ width: '100%', aspectRatio: 1 }}
contentFit="cover"
placeholder={{ blurhash }}
transition={200}
cachePolicy="memory-disk"
/>
| Imkoniyat | Image |
expo-image |
|---|---|---|
| Diskda kesh | Cheklangan | ✅ To'liq |
| Yuklanayotganda placeholder | ❌ | ✅ blurhash / thumbhash |
| Silliq paydo bo'lish | ❌ | ✅ transition |
| WebP, AVIF, GIF, SVG | Qisman | ✅ |
| Xotira samaradorligi | O'rtacha | Yaxshi |
contentFit — resizeMode ning o'rni (CSS object-fit qiymatlari bilan).
Blurhash — rasmning xira "soyasi", 20-30 belgili qator. Server uni rasm bilan birga yuboradi; foydalanuvchi bo'sh kulrang kvadrat o'rniga rasmning taxminiy ranglarini darhol ko'radi.
Fon rasmi: ImageBackground
import { ImageBackground, Text } from 'react-native';
<ImageBackground
source={require('@/assets/images/banner.jpg')}
style={{ width: '100%', height: 180, justifyContent: 'flex-end' }}
imageStyle={{ borderRadius: 16 }}
>
<Text style={{ color: 'white', fontSize: 22, fontWeight: '700', padding: 16 }}>
Yozgi chegirmalar
</Text>
</ImageBackground>
expo-image bilan xuddi shu ish — position: 'absolute' li rasm va ustida kontent.
Xato va yuklanish holatlari
const [xato, setXato] = useState(false);
<Image
source={xato ? require('@/assets/images/rasm-yoq.png') : { uri: url }}
onError={() => setXato(true)}
style={styles.rasm}
/>
Server rasmni o'chirib yuborgan yoki tarmoq yo'q bo'lsa — bo'sh joy o'rniga "rasm yo'q" belgisi.
Ikonkalar
Ikonkalar uchun PNG emas — vektor shriftlar. Expo da tayyor:
import { Ionicons, MaterialIcons, Feather } from '@expo/vector-icons';
<Ionicons name="cart-outline" size={24} color="#0284c7" />
<Feather name="heart" size={20} color="red" />
Minglab ikonka, istalgan o'lcham va rangda. Ro'yxat: https://icons.expo.fyi
Tezlik
- Server katta rasm yuborsa (4000×3000), lekin ekranda 100×100 ko'rsatilsa — telefon xotirasi va trafigi isrof bo'ladi. Serverdan kerakli o'lchamdagi rasmni so'rang (
?w=300) - Uzun ro'yxatlarda
expo-imagekeshlash bilan - Mahalliy rasmlarni optimallang (TinyPNG,
npx expo-optimize)
Nima uchun shunday?
Nima uchun React Native tarmoqdagi rasmning o'lchamini o'zi aniqlamaydi, brauzer esa aniqlaydi?
Brauzer rasm yuklangandan keyin sahifani qayta joylashtiradi — kontent "sakraydi" (layout shift). Vebda bu ko'pincha qabul qilinadi. Mobil ilovada esa elementlarning sakrashi juda sezilarli va bezovta qiladi, ayniqsa ro'yxatda scroll paytida. React Native layoutni rasm yuklanishidan oldin hisoblashni talab qiladi — shuning uchun o'lchamni siz berasiz. Natija — barqaror, sakramaydigan interfeys.
Xulosa
Eslab qoling:
- Mahalliy:
source={require('...png')}; tarmoqdagi:source={{ uri }} - Tarmoqdagi rasmga o'lcham majburiy:
width/heightyokiaspectRatio resizeMode(yokicontentFit):cover,contain- Real ilovada —
expo-image: kesh, blurhash placeholder, transition ImageBackground— fon rasmi ustida kontentonError— rasm yuklanmasa zaxira- Ikonkalar —
@expo/vector-icons
Keyingi dars
8-dars: ScrollView — aylantiriladigan ekran, qachon ishlatmaslik