Урок 01

Стили: StyleSheet и объекты

В React Native нет CSS. Стили — это JavaScript-объекты, передаваемые в проп style.

Inline-стиль

<View style={{ backgroundColor: 'red', padding: 16 }} />

Работает, но создаёт новый объект при каждом рендере.

StyleSheet.create

import { StyleSheet } from 'react-native';

const styles = StyleSheet.create({
    container: {
        flex: 1,
        backgroundColor: '#fff',
        padding: 16,
    },
});

<View style={styles.container} />

Плюсы:

  • Валидация свойств и значений
  • Оптимизация (объекты создаются один раз)
  • Автодополнение в редакторе
  • Меньше мусора

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

В вебе — className и CSS-файлы. В React Native — style и объекты. Никаких классов и каскада.

Свойства в camelCase

// CSS
background-color: red;
font-size: 16px;
margin-top: 8px;

// React Native
backgroundColor: 'red',
fontSize: 16,
marginTop: 8,

Значения

  • Числа — для размеров (width: 100)
  • Строки — для цветов ('#fff', 'red', 'rgba(0,0,0,0.5)')
  • Проценты — '100%', '50%' (для размеров)
  • Без единиц — fontSize: 16, не '16px'

Комбинирование

Массив:

<View style={[styles.base, styles.primary]} />

Последний выигрывает:

<View style={[styles.base, { padding: 20 }]} />
// padding из второго объекта

Условно:

<View style={[styles.base, isActive && styles.active]} />

Если isActive false — false игнорируется.

Наследование

В React Native стили не наследуются, кроме текстовых свойств внутри <Text>:

<Text style={{ fontSize: 20, color: 'red' }}>
    Красный текст, <Text style={{ fontWeight: 'bold' }}>жирный</Text>
</Text>

Вложенный <Text> наследует fontSize и color, но fontWeight переопределяется.

Переменные

const colors = {
    primary: '#c1442e',
    text: '#1a1a1a',
    muted: '#666',
    border: '#e5e5e5',
};

const styles = StyleSheet.create({
    title: { color: colors.text },
    button: { backgroundColor: colors.primary },
});

Или через контекст темы.

Platform.select

Разные стили для iOS и Android:

const styles = StyleSheet.create({
    card: {
        ...Platform.select({
            ios: { shadowColor: '#000', shadowOpacity: 0.1, shadowRadius: 4 },
            android: { elevation: 4 },
        }),
    },
});

Абсолютное позиционирование

const styles = StyleSheet.create({
    overlay: {
        position: 'absolute',
        top: 0, right: 0, bottom: 0, left: 0,
        backgroundColor: 'rgba(0,0,0,0.5)',
    },
});

Готовые библиотеки

  • NativeWind — Tailwind для React Native
  • styled-components — CSS-in-JS
  • restyle — типизированные темы
  • tamagui — UI-кит

Для начала достаточно StyleSheet. Библиотеки — когда проект растёт.

Итоги

  • Стили — объекты
  • StyleSheet.create — предпочтительно
  • camelCase, без единиц
  • Комбинирование массивом
  • Нет наследования, кроме Text
  • Platform.select для различий