Image va expo-image — mahalliy va tarmoqdagi rasmlar

~12 daq · React Native · Asosiy komponentlar

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-image keshlash 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/height yoki aspectRatio
  • resizeMode (yoki contentFit): cover, contain
  • Real ilovada — expo-image: kesh, blurhash placeholder, transition
  • ImageBackground — fon rasmi ustida kontent
  • onError — rasm yuklanmasa zaxira
  • Ikonkalar — @expo/vector-icons

Keyingi dars

8-dars: ScrollView — aylantiriladigan ekran, qachon ishlatmaslik