логотип PurpleSchool
логотип PurpleSchool

Руководство по стилизации компонентов в React Native

Автор

Олег Марков

Введение

Стилизация компонентов — один из ключевых аспектов разработки мобильных приложений на React Native. В отличие от веб-разработки, где для оформления используется CSS, в React Native применяется собственный подход к описанию внешнего вида элементов. В этом руководстве вы подробно познакомитесь с базовыми принципами стилизации, узнаете о возможностях динамической смены стилей, кастомизации их под различные платформы и использования популярных библиотек. Я подготовил структурированный материал с практическими примерами, объясню, как применять различные техники на практике, чтобы ваши компоненты выглядели и работали именно так, как планируется.

Основные способы стилизации в React Native

Использование объекта стилей (Inline Styles)

В React Native вы описываете стили в виде простых JavaScript-объектов, передавая их, как значение свойства style компонентам.

Пример: ```javascript import React from 'react'; import { View, Text } from 'react-native';

const MyComponent = () => ( Этот текст оформлен с помощью inline-стиля ); ``` В этом примере:

  • Вы передаете объект стилей непосредственно в атрибут style
  • Такой подход подходит для простых или динамических стилей, но не удобен для переиспользования

Стилизация компонентов - важная часть разработки React Native приложения. Правильная стилизация позволяет создавать привлекательные и узнаваемые пользовательские интерфейсы. В React Native существует несколько способов стилизации компонентов, включая inline стили, StyleSheet API и CSS-in-JS библиотеки. Чтобы создавать красивые и гармоничные интерфейсы, важно понимать, как работают стили в React Native и уметь их правильно использовать. Если вы хотите детально разобраться в стилизации компонентов в React Native и создавать привлекательные интерфейсы — приходите на наш большой курс React Native и Expo Router. На курсе 184 уроков и 11 упражнений, AI-тренажеры для безлимитной практики с кодом и задачами 24/7, решение задач с живым ревью наставника, еженедельные встречи с менторами.

Статичные стили с помощью StyleSheet

В большинстве случаев предпочтительней использовать модуль StyleSheet:

import React from 'react';
import { StyleSheet, View, Text } from 'react-native';

const styles = StyleSheet.create({
  container: {
    backgroundColor: '#fff',
    padding: 20,
    borderRadius: 8,
  },
  text: {
    fontSize: 16,
    color: '#222',
  },
});

const MyComponent = () => (
  <View style={styles.container}>
    <Text style={styles.text}>
      Это базовый подход с использованием StyleSheet
    </Text>
  </View>
);

Что здесь происходит:

  • Вы создаете объект styles через StyleSheet.create
  • Для каждого элемента задаете нужный стиль, что удобно для поддержки и повторного использования

Преимущества StyleSheet:

  • Валидируется на этапе разработки (ошибки проще отлавливать)
  • Перформанс чуть лучше, чем у inline-стилей, из-за оптимизации самого StyleSheet
  • Удобное переиспользование и структурирование кода

Наследование и объединение стилей

React Native не поддерживает CSS-наследование напрямую, но вы можете комбинировать несколько стилей через массив:

<Text style={[styles.text, { color: 'green' }]}>
  Этот текст частично переопределяет базовый стиль
</Text>
  • Здесь вы переопределяете цвет текста локально для этого компонента
  • Стили применяются слева направо: свойства последующих объектов стилей перекрывают предыдущие

Динамические стили

Иногда требуется менять стили в зависимости от состояния или пропсов. В React Native можно формировать объект стиля динамически:

const MyButton = ({ active }) => (
  <View
    style={[
      styles.button,
      active && styles.activeButton // Если active == true, применяется дополнительный стиль
    ]}
  >
    <Text style={styles.buttonLabel}>Кнопка</Text>
  </View>
);

const styles = StyleSheet.create({
  button: {
    backgroundColor: '#ccc',
    padding: 16,
    borderRadius: 6,
  },
  activeButton: {
    backgroundColor: '#2196f3',
  },
  buttonLabel: {
    color: '#fff',
    fontWeight: 'bold',
  },
});
  • Обратите внимание: условные стили помогают управлять внешним видом компонентов в разных состояниях

Стилизация на основе платформы (Platform-specific styles)

Иногда ваше приложение выглядит иначе на Android и iOS или требует специфических свойств. React Native предлагает два основных способа для таких случаев.

Использование модуля Platform

import { Platform, StyleSheet } from 'react-native';

const styles = StyleSheet.create({
  button: {
    ...Platform.select({
      ios: {
        backgroundColor: 'blue',
      },
      android: {
        backgroundColor: 'green',
      },
      default: {
        backgroundColor: 'gray',
      },
    }),
  },
});
  • Модуль Platform позволяет задать отдельные значения для разных платформ

Расширения файлов стилей

Вы также можете создавать отдельные файлы с расширениями .ios.js и .android.js:

  • Button.ios.js для iOS
  • Button.android.js для Android

React Native сам выберет нужный файл в зависимости от платформы запуска.

Глобальные стили

Если вам нужно хранить общие константы цветов, размеров или использовать общие стили между экранами, создайте отдельный файл, например, styles.js:

// styles.js
import { StyleSheet } from 'react-native';

export const COLORS = {
  primary: '#2196f3',
  secondary: '#e53935',
};

export const GLOBAL = StyleSheet.create({
  header: {
    backgroundColor: COLORS.primary,
    padding: 16,
  },
  title: {
    fontWeight: 'bold',
    fontSize: 20,
    color: '#fff',
  },
});
  • Так получается централизованное хранение стилей и переменных
  • Импортируйте нужные стили в разные компоненты — очень удобно, если проект растет

Работа с медиа-запросами и отзывчивость

В мобильной разработке устройство с разными размерами экранов — норма, поэтому важно предусмотреть отзывчивость (responsiveness).

React Native предлагает стандартные средства:

  • Использование Dimensions для получения ширины и высоты экрана
  • Работа с % в некоторых свойствах (например, width: '50%')
  • Использование библиотеки react-native-responsive-screen или react-native-size-matters

Пример с использованием Dimensions: ```javascript import { Dimensions, StyleSheet } from 'react-native'; const { width } = Dimensions.get('window');

const styles = StyleSheet.create({ box: { width: width * 0.9, // 90% ширины экрана height: 120, backgroundColor: '#fefefe', }, }); ```

  • Размеры пересчитываются при повороте экрана — вы можете использовать слушатель событий для обновления

Использование кастомных хуков для адаптивных стилей

Для более серьезных сценариев вы можете создать собственный хук:

import { useState, useEffect } from 'react';
import { Dimensions } from 'react-native';

const useWindowDimensions = () => {
  const [dimensions, setDimensions] = useState(Dimensions.get('window'));

  useEffect(() => {
    const onChange = ({ window }) => setDimensions(window);
    Dimensions.addEventListener('change', onChange);

    return () => Dimensions.removeEventListener('change', onChange);
  }, []);

  return dimensions;
};

Применяйте этот хук для вычисления и применения стилей на основе размеров экрана.

Стилизация с помощью сторонних библиотек

Styled-components

Многие разработчики уже знакомы с styled-components из мира веба — в React Native библиотека работает примерно так же.

import styled from 'styled-components/native';

const StyledButton = styled.TouchableOpacity`
  background-color: ${props => props.active ? '#2196f3' : '#ccc'};
  padding: 16px;
  border-radius: 6px;
`;

const StyledLabel = styled.Text`
  color: #fff;
  font-size: 18px;
`;

const MyButton = ({ active }) => (
  <StyledButton active={active}>
    <StyledLabel>Кнопка</StyledLabel>
  </StyledButton>
);
  • Вся мощь CSS-in-JS и автоматическая обработка пропсов для динамики
  • Пишется декларативно, компонентно, удобно для темыфикации

Emotion

Есть и альтернативы, например, популярная библиотека emotion с аналогичным синтаксисом и поддержкой React Native.

NativeWind

Если вам нравится utility-first подход, обратите внимание на NativeWind — аналог TailwindCSS для React Native.

import { View, Text } from 'react-native';
import 'nativewind';

const MyBox = () => (
  <View className="p-4 rounded-lg bg-blue-500 w-full">
    <Text className="text-white font-bold">Круто и быстро!</Text>
  </View>
);
  • Используйте utility-классы прямо в коде
  • Позволяет быстро создавать прототипы и масштабируемые стили

Темизация приложения

В сложных проектах часто требуется поддержка тем (например, светлая и тёмная). В React Native это достигается вручную или с помощью библиотек (например, react-native-paper или собственного контекста).

Пример простейшей темы на контексте: ```javascript import React, { createContext, useContext } from 'react';

const themes = { light: { background: '#fff', textColor: '#222', }, dark: { background: '#222', textColor: '#fff', }, };

const ThemeContext = createContext(themes.light);

const ThemedView = ({ children }) => { const theme = useContext(ThemeContext);

return ( Пример с темизацией! {children} ); }; ``` Подробнее о более сложных сценариях вы можете узнать в документации по библиотекам.

Анимация и динамическая смена стилей

Для плавного изменения стилей используйте модуль Animated. Он позволяет анимировать изменения, например, цвета, размеров, положения элементов.

import React, { useRef } from 'react';
import { Animated, TouchableOpacity, Text } from 'react-native';

const AnimatedBox = () => {
  const opacity = useRef(new Animated.Value(1)).current;

  const fadeOut = () => {
    Animated.timing(opacity, {
      toValue: 0,
      duration: 500,
      useNativeDriver: true, // Лучше использовать useNativeDriver для производительности
    }).start();
  };

  return (
    <TouchableOpacity onPress={fadeOut}>
      <Animated.View style={{ opacity, backgroundColor: '#2196f3', padding: 20 }}>
        <Text style={{ color: '#fff' }}>Нажмите, чтобы скрыть</Text>
      </Animated.View>
    </TouchableOpacity>
  );
};

Заключение

Стилизация компонентов в React Native устроена не так, как в вебе, и имеет свои особенности и лучшие практики. Вы можете использовать встроенный механизм через StyleSheet, экспериментировать с динамикой и платформ-независимостью, пробовать сторонние решения для темизации и удобства, подключать анимации и каскадировать стили. Очень важно выбрать подходящий способ для вашей задачи — где-то удобны inline-стили и простые объекты, а где-то стоит выносить дизайн в отдельные файлы или использовать библиотеки. Подходите к этому вопросу гибко, и вы сможете добиться аккуратного и поддерживаемого кода при любой сложности приложения.

Стилизация компонентов - это важный, но не единственный аспект разработки качественного React Native приложения. Для создания полноценного приложения необходимо освоить множество других технологий и подходов, включая работу с UI, данными и нативными функциями. Курс React Native и Expo Router поможет вам в этом. В первых 3 модулях уже доступно бесплатное содержание — начните погружаться в мир React Native прямо сегодня.

Частозадаваемые технические вопросы по теме статьи и ответы на них

Вопрос 1: Как объединить несколько объектов стилей из разных файлов, если используются импорты (например, глобальные и локальные)?
Ответ:
Вы можете комбинировать массив стилей, например:
<Text style={[globalStyles.title, localStyles.title]}>Текст</Text>.
Порядок важен: свойства справа перекрывают слева.

Вопрос 2: Возможна ли вложенность стилей как в SCSS?
Ответ:
Нет, в React Native такой механики нет. Вы можете создавать отдельные объекты стилей, а вложенность формировать через структуру компонентов. Для имитации каскадирования используйте наследование props или передавайте имена стилей.

Вопрос 3: Почему не все CSS-свойства поддерживаются?
Ответ:
React Native реализует собственный движок для стилей. Поддерживаются только свойства, релевантные мобильным приложениям (нет, к примеру, float, z-index ограничен и т.д.). Актуальную таблицу поддерживаемых свойств ищите в официальных доках.

Вопрос 4: Можно ли использовать медиа-запросы как в CSS?
Ответ:
Нативно нет, но при помощи вычисления размеров окна (через Dimensions, SafeArea и сторонние библиотеки) вы можете имитировать подобную логику адаптации интерфейса.

Вопрос 5: Почему не применяются изменения в конструкции style={{ ... }} при hot reload?
Ответ:
Иногда hot reload не отслеживает изменения в inline-стилях. Рекомендуется использовать StyleSheet или перезапустить сборку. В сложных случаях обновите Expo/Bundler и проверьте консоль на ошибки.

Стрелочка влевоСоздание и использование tabs в React NativeОптимизация переходов между экранами в React NativeСтрелочка вправо

Постройте личный план изучения React-native до уровня Middle — бесплатно!

React-native — часть карты развития Mobile

  • step100+ шагов развития
  • lessons30 бесплатных лекций
  • lessons300 бонусных рублей на счет

Бесплатные лекции

Все гайды по React-native

Работа со ScrollView в React NativeРабота с видео в React NativeКак реализовать аудиоплеер на React NativeНастройка и использование input и textinput в React NativeИнтеграция видео плеера в приложение на React NativeИспользование выпадающих списков в React NativeСоздание и настройка native module на React NativeКак создать модальные окна в React NativeРабота с изображениями в React NativeОтображение списков данных в React NativeГайд по файловой системе в React NativeИнтеграция камеры в приложение на React NativeСоздание интерактивных кнопок в React Native
Как использовать векторные иконки в React Native5 популярных библиотек UI компонентов React NativeСоздание и использование tabs в React NativeРуководство по стилизации компонентов в React NativeОптимизация переходов между экранами в React NativeАдаптация safe area context на React NativeОбзор библиотек для навигации в React NativeСоздание сложных анимаций (reanimated) на React NativeИспользование библиотеки стилей Paper в React NativeРуководство по navigation в React NativeОптимизация отображения списков в React NativeКак реализовать linking на React NativeГайд по UI-китам для React NativeГде искать elements для приложения на React NativeРабота с цветами в React Native
Открыть базу знаний

Лучшие курсы по теме

изображение курса

React Native и Expo Router

Антон Ларичев
AI-тренажеры
Практика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.7
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

Основы JavaScript

Антон Ларичев
AI-тренажеры
Практика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.8
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

TypeScript с нуля

Антон Ларичев
AI-тренажеры
Практика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.7
3 999 ₽ 6 990 ₽
Подробнее

Отправить комментарий