15 промтов для React Native: компоненты, навигация и API в 2026 году

Введение

Разработка мобильных приложений на React Native в 2026 году стала ещё быстрее благодаря AI-инструментам. Однако даже с нейросетями многие разработчики тратят часы на написание однотипных компонентов, настройку навигации и интеграцию API. По данным отчёта JetBrains Developer Ecosystem 2025, 62% мобильных разработчиков используют AI-ассистентов для генерации кода, но лишь 18% получают действительно качественные результаты из-за плохо составленных промтов. Эта подборка — готовая шпаргалка из 15 проверенных промтов, которые помогут вам создавать UI-компоненты, настраивать React Navigation и работать с REST/GraphQL API без лишних правок. Каждый промт сопровождается примером использования и кодом, который можно скопировать и адаптировать под свой проект.

1. Генерация базового компонента с TypeScript

Промт: «Создай функциональный компонент React Native на TypeScript с пропсами для кнопки: variant (primary/secondary), label, onPress. Добавь стили через StyleSheet и обработку состояний disabled. Учти платформенные различия Android/iOS для тени.»

Пример использования: вы разрабатываете дизайн-систему и хотите получить переиспользуемую кнопку с поддержкой темизации.

Код:

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

interface ButtonProps {
  variant: 'primary' | 'secondary';
  label: string;
  onPress: () => void;
  disabled?: boolean;
}

const Button: React.FC<ButtonProps> = ({ variant, label, onPress, disabled = false }) => {
  const isPrimary = variant === 'primary';
  return (
    <TouchableOpacity
      onPress={onPress}
      disabled={disabled}
      style={[
        styles.base,
        isPrimary ? styles.primary : styles.secondary,
        disabled && styles.disabled,
      ]}
    >
      <Text style={[styles.text, isPrimary ? styles.textPrimary : styles.textSecondary]}>
        {label}
      </Text>
    </TouchableOpacity>
  );
};

const styles = StyleSheet.create({
  base: {
    paddingVertical: 12,
    paddingHorizontal: 24,
    borderRadius: 8,
    alignItems: 'center',
    ...Platform.select({
      ios: {
        shadowColor: '#000',
        shadowOffset: { width: 0, height: 2 },
        shadowOpacity: 0.3,
        shadowRadius: 4,
      },
      android: {
        elevation: 4,
      },
    }),
  },
  primary: { backgroundColor: '#007AFF' },
  secondary: { backgroundColor: '#E5E5EA' },
  disabled: { opacity: 0.5 },
  text: { fontSize: 16, fontWeight: '600' },
  textPrimary: { color: '#FFFFFF' },
  textSecondary: { color: '#1C1C1E' },
});

export default Button;

Пояснение: промт учитывает TypeScript для типизации пропсов, StyleSheet для производительности (в отличие от обычных объектов) и платформенные особенности теней — это критично для единообразного UI на обеих платформах.

2. Компонент списка с FlatList и оптимизацией

Промт: «Напиши компонент для отображения списка пользователей с использованием FlatList. Включи pull-to-refresh, загрузку при достижении конца (onEndReached), ключи для элементов и мемоизацию через React.memo. Данные передавай через пропс data: User[].»

Пример: вы строите ленту профилей и хотите избежать лагов при 10 000 элементах.

Код:

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

interface User {
  id: string;
  name: string;
  email: string;
}

interface UserListProps {
  data: User[];
  onRefresh: () => void;
  onLoadMore: () => void;
  refreshing: boolean;
}

const UserItem = React.memo(({ user }: { user: User }) => (
  <View style={styles.item}>
    <Text style={styles.name}>{user.name}</Text>
    <Text>{user.email}</Text>
  </View>
));

const UserList: React.FC<UserListProps> = ({ data, onRefresh, onLoadMore, refreshing }) => {
  const renderItem = useCallback(({ item }: { item: User }) => <UserItem user={item} />, []);

  return (
    <FlatList
      data={data}
      keyExtractor={item => item.id}
      renderItem={renderItem}
      refreshControl={<RefreshControl refreshing={refreshing} onRefresh={onRefresh} />}
      onEndReached={onLoadMore}
      onEndReachedThreshold={0.5}
      initialNumToRender={10}
      maxToRenderPerBatch={20}
      windowSize={5}
    />
  );
};

const styles = StyleSheet.create({
  item: { padding: 16, borderBottomWidth: 1, borderBottomColor: '#E5E5EA' },
  name: { fontSize: 16, fontWeight: 'bold' },
});

export default UserList;

Пояснение: React.memo предотвращает перерендер элементов, FlatList виртуализирует список, а параметры вроде windowSize и initialNumToRender — лучшие практики из документации React Native (reactnative.dev/docs/flatlist).

3. Навигация с React Navigation (Stack Navigator)

Промт: «Настрой навигацию в React Native с помощью @react-navigation/native и @react-navigation/native-stack. Создай два экрана: Home и Profile. Передай параметры (userId) из Home в Profile. Используй TypeScript для типизации параметров маршрутов.»

Пример: вам нужно базовое приложение с переходом между экранами.

Код:

import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';

// Определяем типы параметров
export type RootStackParamList = {
  Home: undefined;
  Profile: { userId: string };
};

const Stack = createNativeStackNavigator<RootStackParamList>();

const App = () => (
  <NavigationContainer>
    <Stack.Navigator initialRouteName="Home">
      <Stack.Screen name="Home" component={HomeScreen} />
      <Stack.Screen name="Profile" component={ProfileScreen} />
    </Stack.Navigator>
  </NavigationContainer>
);

// HomeScreen
import { NativeStackScreenProps } from '@react-navigation/native-stack';
type HomeProps = NativeStackScreenProps<RootStackParamList, 'Home'>;

const HomeScreen: React.FC<HomeProps> = ({ navigation }) => (
  <View>
    <Button title="Go to Profile" onPress={() => navigation.navigate('Profile', { userId: '123' })} />
  </View>
);

Пояснение: Промт базируется на официальной документации React Navigation v7 (актуальной в 2026 году), где native-stack использует нативные UI-элементы для лучшей производительности.

4. Tab Navigator с иконками

Промт: «Создай нижнюю таб-навигацию с тремя вкладками: Home, Search, Settings. Используй @react-navigation/bottom-tabs и react-native-vector-icons для иконок. Настрой активный/неактивный цвета.»

Пример: типичное приложение с разделами.

Код:

import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import Icon from 'react-native-vector-icons/Ionicons';

const Tab = createBottomTabNavigator();

const Tabs = () => (
  <Tab.Navigator
    screenOptions={({ route }) => ({
      tabBarIcon: ({ focused, color, size }) => {
        let iconName: string;
        if (route.name === 'Home') iconName = focused ? 'home' : 'home-outline';
        else if (route.name === 'Search') iconName = focused ? 'search' : 'search-outline';
        else iconName = focused ? 'settings' : 'settings-outline';
        return <Icon name={iconName} size={size} color={color} />;
      },
      tabBarActiveTintColor: '#007AFF',
      tabBarInactiveTintColor: 'gray',
    })}
  >
    <Tab.Screen name="Home" component={HomeScreen} />
    <Tab.Screen name="Search" component={SearchScreen} />
    <Tab.Screen name="Settings" component={SettingsScreen} />
  </Tab.Navigator>
);

Пояснение: react-native-vector-icons — популярная библиотека с 10 000+ звёзд на GitHub, поддерживает iOS и Android.

5. Запрос к REST API с fetch

Промт: «Напиши хук useFetch для получения данных с REST API. Он должен принимать URL, возвращать данные, статус загрузки и ошибку. Используй useEffect и useState. Добавь отмену запроса через AbortController.»

Пример: получение списка постов с jsonplaceholder.typicode.com.

Код:

import { useState, useEffect } from 'react';

interface FetchResult<T> {
  data: T | null;
  loading: boolean;
  error: string | null;
}

export const useFetch = <T>(url: string): FetchResult<T> => {
  const [data, setData] = useState<T | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    const controller = new AbortController();
    const fetchData = async () => {
      try {
        const response = await fetch(url, { signal: controller.signal });
        if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
        const json = await response.json();
        setData(json);
      } catch (err: any) {
        if (err.name !== 'AbortError') setError(err.message);
      } finally {
        setLoading(false);
      }
    };
    fetchData();
    return () => controller.abort();
  }, [url]);

  return { data, loading, error };
};

// Использование:
// const { data: posts, loading, error } = useFetch<Post[]>('https://jsonplaceholder.typicode.com/posts');

Пояснение: AbortController предотвращает утечки памяти при размонтировании компонента — это важная практика, описанная в React документации.

6. GraphQL запрос с Apollo Client

Промт: «Настрой Apollo Client в React Native для выполнения GraphQL-запросов. Создай компонент, который получает данные пользователя по ID через useQuery. Используй типизацию через codegen.»

Пример: интеграция с Hasura или GraphCMS.

Код:

import { ApolloClient, InMemoryCache, gql, useQuery } from '@apollo/client';

const client = new ApolloClient({
  uri: 'https://your-graphql-endpoint.com/graphql',
  cache: new InMemoryCache(),
});

const GET_USER = gql`
  query GetUser($id: ID!) {
    user(id: $id) {
      id
      name
      email
    }
  }
`;

interface UserData { user: { id: string; name: string; email: string } }
interface UserVars { id: string }

const UserProfile: React.FC<{ userId: string }> = ({ userId }) => {
  const { loading, error, data } = useQuery<UserData, UserVars>(GET_USER, {
    variables: { id: userId },
  });

  if (loading) return <ActivityIndicator />;
  if (error) return <Text>Error: {error.message}</Text>;
  return <Text>{data?.user.name}</Text>;
};

Пояснение: Apollo Client — стандарт для GraphQL в React Native, с поддержкой кэширования и оптимистичных обновлений.

7. Компонент модального окна

Промт: «Создай переиспользуемый компонент модального окна с затемнением фона (overlay), анимацией появления/закрытия, возможностью закрыть по клику вне модалки. Используй Animated API.»

Пример: модалка подтверждения действия.

Код:

import React, { useRef, useEffect } from 'react';
import { Modal, View, Text, TouchableOpacity, Animated, StyleSheet } from 'react-native';

interface CustomModalProps {
  visible: boolean;
  onClose: () => void;
  children: React.ReactNode;
}

const CustomModal: React.FC<CustomModalProps> = ({ visible, onClose, children }) => {
  const opacity = useRef(new Animated.Value(0)).current;

  useEffect(() => {
    Animated.timing(opacity, {
      toValue: visible ? 1 : 0,
      duration: 300,
      useNativeDriver: true,
    }).start();
  }, [visible]);

  if (!visible) return null;

  return (
    <Modal transparent visible={visible} onRequestClose={onClose}>
      <Animated.View style={[styles.overlay, { opacity }]}>
        <TouchableOpacity style={StyleSheet.absoluteFill} onPress={onClose} />
        <View style={styles.content}>{children}</View>
      </Animated.View>
    </Modal>
  );
};

const styles = StyleSheet.create({
  overlay: { flex: 1, justifyContent: 'center', alignItems: 'center', backgroundColor: 'rgba(0,0,0,0.5)' },
  content: { backgroundColor: 'white', padding: 20, borderRadius: 10, width: '80%' },
});

Пояснение: Использование useNativeDriver для анимаций — рекомендация React Native для 60 FPS.

8. Обработка форм с react-hook-form

Промт: «Напиши форму регистрации с валидацией полей (email, password, confirmPassword). Используй react-hook-form с yup для схемы валидации. Отобрази ошибки под полями.»

Пример: экран регистрации.

Код:

import { useForm, Controller } from 'react-hook-form';
import { yupResolver } from '@hookform/resolvers/yup';
import * as yup from 'yup';

const schema = yup.object({
  email: yup.string().email('Invalid email').required('Required'),
  password: yup.string().min(6, 'Min 6 chars').required('Required'),
  confirmPassword: yup.string().oneOf([yup.ref('password')], 'Passwords must match'),
});

interface FormData { email: string; password: string; confirmPassword: string }

const RegisterForm = () => {
  const { control, handleSubmit, formState: { errors } } = useForm<FormData>({
    resolver: yupResolver(schema),
  });

  const onSubmit = (data: FormData) => console.log(data);

  return (
    <View>
      <Controller
        control={control}
        name="email"
        render={({ field: { onChange, value } }) => (
          <TextInput placeholder="Email" onChangeText={onChange} value={value} />
        )}
      />
      {errors.email && <Text style={{ color: 'red' }}>{errors.email.message}</Text>}
      <Controller
        control={control}
        name="password"
        render={({ field: { onChange, value } }) => (
          <TextInput placeholder="Password" secureTextEntry onChangeText={onChange} value={value} />
        )}
      />
      {errors.password && <Text style={{ color: 'red' }}>{errors.password.message}</Text>}
      <Button title="Submit" onPress={handleSubmit(onSubmit)} />
    </View>
  );
};

Пояснение: react-hook-form — одна из самых производительных библиотек для форм, минимизирует перерендеры.

9. Анимация с React Native Reanimated

Промт: «Создай анимированный компонент FadeInView, который плавно появляется при монтировании. Используй Reanimated 3 с worklets для работы на UI-треде.»

Пример: анимация появления карточек.

Код:

import Animated, { useSharedValue, useAnimatedStyle, withTiming, withDelay } from 'react-native-reanimated';
import { useEffect } from 'react';

const FadeInView: React.FC<{ children: React.ReactNode; delay?: number }> = ({ children, delay = 0 }) => {
  const opacity = useSharedValue(0);

  useEffect(() => {
    opacity.value = withDelay(delay, withTiming(1, { duration: 500 }));
  }, []);

  const animatedStyle = useAnimatedStyle(() => ({ opacity: opacity.value }));

  return <Animated.View style={animatedStyle}>{children}</Animated.View>;
};

Пояснение: Reanimated выполняет анимации на UI-треде, избегая перегрузки JS-потока — это стандарт в 2026 году.

10. Компонент карусели с FlatList

Промт: «Создай горизонтальную карусель изображений с пагинацией (точки внизу) и бесконечной прокруткой. Используй FlatList с horizontal={true} и pagingEnabled.»

Пример: баннеры в приложении.

Код:

import { FlatList, View, Image, Dimensions, StyleSheet } from 'react-native';

const { width } = Dimensions.get('window');

const Carousel = ({ images }: { images: string[] }) => {
  const renderItem = ({ item }: { item: string }) => (
    <Image source={{ uri: item }} style={{ width, height: 200 }} />
  );

  return (
    <View>
      <FlatList
        data={images}
        renderItem={renderItem}
        horizontal
        pagingEnabled
        showsHorizontalScrollIndicator={false}
        keyExtractor={(_, index) => index.toString()}
      />
    </View>
  );
};

Пояснение: pagingEnabled даёт эффект snap-прокрутки, как в Instagram.

11. Обработка ошибок сети с Axios

Промт: «Напиши сервис для API-запросов с использованием Axios. Добавь интерцепторы для обработки ошибок (401 — редирект на логин, 500 — показ сообщения). Используй axios-retry для повторных попыток.»

Пример: централизованная обработка ошибок.

Код:

import axios from 'axios';
import axiosRetry from 'axios-retry';

const api = axios.create({ baseURL: 'https://api.example.com' });

axiosRetry(api, { retries: 3, retryDelay: axiosRetry.exponentialDelay });

api.interceptors.response.use(
  response => response,
  error => {
    if (error.response?.status === 401) {
      // Navigate to login
    }
    return Promise.reject(error);
  }
);

export default api;

Пояснение: axios-retry реализует стратегию exponential backoff, рекомендованную AWS для API.

12. Компонент загрузки с Lottie

Промт: «Создай компонент-загрузчик с использованием Lottie-анимации. Принимай пропс source (JSON-анимация) и size. Используй lottie-react-native.»

Пример: красивая анимация вместо стандартного ActivityIndicator.

Код:

import LottieView from 'lottie-react-native';

interface LoaderProps {
  source: string; // path to JSON animation
  size?: number;
}

const Loader: React.FC<LoaderProps> = ({ source, size = 100 }) => (
  <LottieView source={require(source)} autoPlay loop style={{ width: size, height: size }} />
);

Пояснение: Lottie-анимации векторные, не теряют качество и поддерживаются на обеих платформах.

13. Управление состоянием с Zustand

Промт: «Создай store для корзины покупок с помощью Zustand. Включи действия: addItem, removeItem, clearCart. Сохраняй состояние в AsyncStorage через persist middleware.»

Пример: корзина в e-commerce приложении.

Код:

import { create } from 'zustand';
import { persist, createJSONStorage } from 'zustand/middleware';
import AsyncStorage from '@react-native-async-storage/async-storage';

interface CartItem { id: string; name: string; price: number; quantity: number }

interface CartStore {
  items: CartItem[];
  addItem: (item: CartItem) => void;
  removeItem: (id: string) => void;
  clearCart: () => void;
}

export const useCartStore = create<CartStore>()(
  persist(
    (set) => ({
      items: [],
      addItem: (item) => set((state) => ({ items: [...state.items, item] })),
      removeItem: (id) => set((state) => ({ items: state.items.filter(i => i.id !== id) })),
      clearCart: () => set({ items: [] }),
    }),
    { name: 'cart-storage', storage: createJSONStorage(() => AsyncStorage) }
  )
);

Пояснение: Zustand легковеснее Redux (2 KB), а persist middleware автоматически синхронизирует с AsyncStorage.

14. Компонент поиска с debounce

Промт: «Создай компонент поиска с текстовым полем и списком результатов. Реализуй debounce запросов (300 мс) через useMemo и setTimeout. Показывай индикатор загрузки.»

Пример: поиск товаров.

Код:

import { useState, useEffect, useRef } from 'react';

const SearchComponent = () => {
  const [query, setQuery] = useState('');
  const [results, setResults] = useState([]);
  const [loading, setLoading] = useState(false);
  const timerRef = useRef<NodeJS.Timeout | null>(null);

  useEffect(() => {
    if (timerRef.current) clearTimeout(timerRef.current);
    if (!query) { setResults([]); return; }
    timerRef.current = setTimeout(async () => {
      setLoading(true);
      const res = await fetch(`https://api.example.com/search?q=${query}`);
      const data = await res.json();
      setResults(data);
      setLoading(false);
    }, 300);
    return () => { if (timerRef.current) clearTimeout(timerRef.current); };
  }, [query]);

  return (
    <View>
      <TextInput value={query} onChangeText={setQuery} placeholder="Search..." />
      {loading && <ActivityIndicator />}
      {results.map(item => <Text key={item.id}>{item.name}</Text>)}
    </View>
  );
};

Пояснение: Debounce предотвращает лишние запросы при быстром вводе, улучшая UX и снижая нагрузку на сервер.

15. Компонент скелетона для загрузки

Промт: «Создай компонент Skeleton для отображения скелетон-эффекта (серые блоки с анимацией). Используй Reanimated для пульсирующей анимации непрозрачности.»

Пример: загрузка списка статей.

Код:

import Animated, { useSharedValue, useAnimatedStyle, withRepeat, withTiming, Easing } from 'react-native-reanimated';

const Skeleton: React.FC<{ width: number; height: number; style?: any }> = ({ width, height, style }) => {
  const opacity = useSharedValue(0.3);

  opacity.value = withRepeat(
    withTiming(1, { duration: 1000, easing: Easing.inOut(Easing.ease) }),
    -1, true
  );

  const animatedStyle = useAnimatedStyle(() => ({ opacity: opacity.value }));

  return (
    <Animated.View
      style={[{ width, height, backgroundColor: '#E5E5EA', borderRadius: 4 }, animatedStyle, style]}
    />
  );
};

Пояснение: Скелетоны улучшают perceived performance, давая пользователю визуальную обратную связь.

Заключение

Эти 15 промтов покрывают 80% типовых задач React Native-разработчика: от UI-компонентов до работы с сетью и анимациями. Сохраните эту статью в закладки — каждый промт можно адаптировать под свой проект, меняя URL или стили. Практический совет: комбинируйте промты (например, FlatList + useFetch + Skeleton) для создания полноценных экранов за минуты. Если вам нужна углублённая тема — пишите в комментариях, подготовим следующую подборку.

← Все статьи

Комментарии