Урок 03

Изображения и иконки

Image

Локальные:

<Image source={require('./assets/logo.png')} style={{ width: 100, height: 100 }} />

Сетевые:

<Image
    source={{ uri: 'https://example.com/image.jpg' }}
    style={{ width: 200, height: 200 }}
/>

Обязательно указывай размеры для сетевых изображений — они не могут определить размер автоматически.

resizeMode

resizeMode="cover"     // заполняет, обрезая
resizeMode="contain"   // вписывает целиком
resizeMode="stretch"   // растягивает
resizeMode="repeat"    // повторяет
resizeMode="center"    // по центру без масштаба

Placeholder и ошибки

<Image
    source={{ uri: url }}
    style={styles.image}
    defaultSource={require('./placeholder.png')}
    onLoad={() => setLoading(false)}
    onError={() => setError(true)}
/>

С состоянием загрузки:

function Avatar({ uri }: { uri: string }) {
    const [loading, setLoading] = useState(true);

    return (
        <View style={styles.avatarWrap}>
            {loading && <ActivityIndicator />}
            <Image
                source={{ uri }}
                style={styles.avatar}
                onLoadEnd={() => setLoading(false)}
            />
        </View>
    );
}

Локальные картинки

// Статический require
<Image source={require('./icon.png')} />

// Динамически — нельзя через переменную
const icon = require('./icon.png');
<Image source={icon} />

require работает только со строковыми литералами — статический анализ.

expo-image

Современная замена. Лучше кеширует, работает с blurhash, даёт больше контроля:

npx expo install expo-image
import { Image } from 'expo-image';

<Image
    source={{ uri: url }}
    placeholder={{ blurhash: 'L6PZfSi_.AyE_3t7t7R**0o#DgR4' }}
    contentFit="cover"
    transition={200}
    style={{ width: 200, height: 200 }}
/>

Иконки

Стандарт — @expo/vector-icons (входит в Expo):

import { Ionicons, MaterialIcons, Feather } from '@expo/vector-icons';

<Ionicons name="heart" size={24} color="red" />
<MaterialIcons name="home" size={24} color="#333" />
<Feather name="search" size={20} color="#666" />

Наборы:

  • Ionicons — 1300+ иконок
  • MaterialIcons — Material Design
  • Feather — минималистичные
  • FontAwesome — классика
  • AntDesign — Ant Design

Просмотр: icons.expo.fyi

SVG

npx expo install react-native-svg
import Svg, { Circle, Path } from 'react-native-svg';

<Svg width="100" height="100" viewBox="0 0 100 100">
    <Circle cx="50" cy="50" r="40" fill="red" />
</Svg>

Или через .svg файлы:

npx expo install react-native-svg-transformer
import Logo from './logo.svg';

<Logo width={100} height={100} fill="red" />

Фоны

<ImageBackground
    source={require('./bg.jpg')}
    style={styles.bg}
    imageStyle={styles.bgImage}
>
    <Text style={styles.text}>Поверх фона</Text>
</ImageBackground>

Если ты уже знаешь React

В вебе — <img src="..." alt="..." />. В React Native — <Image source={...} />. Нет alt, нужны размеры, resizeMode вместо object-fit.

Итоги

  • Image вместо img
  • source вместо src
  • Размеры обязательны
  • resizeMode вместо object-fit
  • expo-image — современная замена
  • @expo/vector-icons для иконок