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

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

Каждый день я как разработчик React Native пишу однотипные запросы в AI, чтобы ускорить работу. Chat‑GPT, Claude или Copilot — неважно, главное — правильно сформулировать промт. В этой подборке — 10 проверенных формулировок, которые я сам использую для UI‑компонентов, навигации, работы с API и оптимизации. Никакой воды — только конкретика с кодом и результатами.

1. Создание кастомного компонента с динамическими пропсами

Проблема: Нужно быстро набросать переиспользуемый компонент UserCard с поддержкой разных состояний (загрузка, ошибка, данные). Писать с нуля вручную — терять время.

Промт:

Напиши React Native компонент UserCard, который принимает пропсы name, email, avatarUrl, loading и error. В состоянии загрузки покажи ActivityIndicator, при ошибке — текст ошибки, иначе — аватар, имя и email. Используй StyleSheet. Верни готовый код.

Результат:

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

interface UserCardProps {
  name?: string;
  email?: string;
  avatarUrl?: string;
  loading: boolean;
  error?: string | null;
}

const UserCard: React.FC<UserCardProps> = ({ name, email, avatarUrl, loading, error }) => {
  if (loading) return <ActivityIndicator size="large" color="#0000ff" />;
  if (error) return <Text style={styles.error}>{error}</Text>;
  return (
    <View style={styles.card}>
      <Image source={{ uri: avatarUrl }} style={styles.avatar} />
      <Text style={styles.name}>{name}</Text>
      <Text style={styles.email}>{email}</Text>
    </View>
  );
};

export default UserCard;

Вывод: Промт экономит 5–10 минут ручного написания и покрывает типичные кейсы. Адаптируй под свои типы — и в бой.

2. FlatList с бесконечной подгрузкой

Проблема: Реализовать ленту постов с пагинацией и индикатором загрузки в конце списка. Частая задача, но нужно не забыть про onEndReached и useCallback.

Промт:

Напиши компонент InfiniteList на React Native с FlatList, который принимает data, renderItem, loadMore (функция), hasMore (boolean). При достижении конца списка (onEndReached) вызывай loadMore, покажи ActivityIndicator в Footer, если hasMore true. Используй useCallback для loadMore. Верни полный код компонента.

Результат:

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

interface InfiniteListProps<T> {
  data: T[];
  renderItem: ({ item }: { item: T }) => JSX.Element;
  loadMore: () => void;
  hasMore: boolean;
}

function InfiniteList<T>({ data, renderItem, loadMore, hasMore }: InfiniteListProps<T>) {
  const handleLoadMore = useCallback(() => {
    if (hasMore) loadMore();
  }, [hasMore, loadMore]);

  const footer = hasMore ? <ActivityIndicator style={styles.footer} /> : null;

  return (
    <FlatList
      data={data}
      renderItem={renderItem}
      keyExtractor={(_, index) => index.toString()}
      onEndReached={handleLoadMore}
      onEndReachedThreshold={0.5}
      ListFooterComponent={footer}
    />
  );
}

export default InfiniteList;

Вывод: Универсальный компонент для любой версии React Native. Меняй keyExtractor под свой тип данных — готово.

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

Проблем: Нужно настроить связку Stack Navigator в модальном режиме и нижние табы. Документация хороша, но промт даёт скелет за секунду.

Промт:

Напиши конфигурацию React Navigation для приложения: Bottom Tab Navigator с тремя вкладками (Home, Search, Profile). Внутри Home используй Stack Navigator с экранами HomeScreen и DetailsScreen. Покажи код с NavigationContainer, createBottomTabNavigator, createNativeStackNavigator. Используй Typescript.

Результат:

import React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import HomeScreen from '../screens/HomeScreen';
import DetailsScreen from '../screens/DetailsScreen';
import SearchScreen from '../screens/SearchScreen';
import ProfileScreen from '../screens/ProfileScreen';

type HomeStackParamList = {
  Home: undefined;
  Details: { itemId: number };
};

const Stack = createNativeStackNavigator<HomeStackParamList>();
const Tab = createBottomTabNavigator();

function HomeStack() {
  return (
    <Stack.Navigator>
      <Stack.Screen name="Home" component={HomeScreen} />
      <Stack.Screen name="Details" component={DetailsScreen} />
    </Stack.Navigator>
  );
}

export default function AppNavigator() {
  return (
    <NavigationContainer>
      <Tab.Navigator>
        <Tab.Screen name="Home" component={HomeStack} />
        <Tab.Screen name="Search" component={SearchScreen} />
        <Tab.Screen name="Profile" component={ProfileScreen} />
      </Tab.Navigator>
    </NavigationContainer>
  );
}

Вывод: Подходит для 90% приложений. Добавь иконки через tabBarIcon — и готово.

4. Кастомный хук для запроса данных (fetch / axios)

Проблем: Не хочется дублировать логику загрузки, ошибок и отмены запросов. Нужен хук useFetch.

Промт:

Напиши кастомный хук useFetch<T>(url: string, options?: RequestInit) на TypeScript для React Native, который возвращает `{ data: T

| null, loading: boolean, error: string | null, refetch: () => void }`. Используй useEffect с очисткой (AbortController). Пример с fetch. Верни код.

Результат:

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

interface UseFetchResult<T> {
  data: T | null;
  loading: boolean;
  error: string | null;
  refetch: () => void;
}

export function useFetch<T>(url: string, options?: RequestInit): UseFetchResult<T> {
  const [data, setData] = useState<T | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const abortRef = useRef<AbortController | null>(null);

  const fetchData = useCallback(async () => {
    abortRef.current?.abort();
    const controller = new AbortController();
    abortRef.current = controller;
    setLoading(true);
    setError(null);

    try {
      const response = await fetch(url, { ...options, signal: controller.signal });
      if (!response.ok) throw new Error(`HTTP ${response.status}`);
      const json = await response.json();
      setData(json as T);
    } catch (err: any) {
      if (err.name !== 'AbortError') setError(err.message);
    } finally {
      setLoading(false);
    }
  }, [url, options]);

  useEffect(() => {
    fetchData();
    return () => abortRef.current?.abort();
  }, [fetchData]);

  return { data, loading, error, refetch: fetchData };
}

Вывод: Хук избавляет от бойлерплейта. Замени fetch на axios по аналогии.

5. Анимированный вход/выход компонента (Animated API)

Проблем: Нужно добавить плавное появление модального окна или тултипа. Вручную писать анимации долго.

Промт:

Напиши React Native компонент FadeInView, который оборачивает дочерние элементы и анимирует появление с прозрачностью от 0 до 1 при монтировании. Используй Animated.Value, Animated.timing. Длительность 300ms. Используй функциональный компонент с хуками.

Результат:

import React, { useRef, useEffect } from 'react';
import { Animated, ViewStyle } from 'react-native';

interface FadeInViewProps {
  style?: ViewStyle;
  children: React.ReactNode;
}

const FadeInView: React.FC<FadeInViewProps> = ({ style, children }) => {
  const opacity = useRef(new Animated.Value(0)).current;

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

  return (
    <Animated.View style={[{ opacity }, style]}>
      {children}
    </Animated.View>
  );
};

export default FadeInView;

Вывод: Минимум кода — максимум эффекта. Легко расширить до анимации сдвига или масштаба.

6. Обработка клавиатуры (KeyboardAvoidingView + dismiss)

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

Промт:

Напиши компонент KeyboardSafeView, который оборачивает контент в KeyboardAvoidingView (поведение 'padding' для iOS, 'height' для Android) и добавляет TouchableWithoutFeedback для скрытия клавиатуры по тапу вне поля ввода. Используй Platform.

Результат:

import React from 'react';
import {
  KeyboardAvoidingView,
  TouchableWithoutFeedback,
  Keyboard,
  Platform,
  StyleSheet,
  ViewProps,
} from 'react-native';

const KeyboardSafeView: React.FC<ViewProps> = ({ children, style }) => {
  return (
    <KeyboardAvoidingView
      behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
      style={[styles.container, style]}
    >
      <TouchableWithoutFeedback onPress={Keyboard.dismiss}>
        {children}
      </TouchableWithoutFeedback>
    </KeyboardAvoidingView>
  );
};

const styles = StyleSheet.create({
  container: { flex: 1 },
});

export default KeyboardSafeView;

Вывод: Единый компонент для обеих платформ. Экономит часы дебага адаптации.

7. Скелетон загрузки (Skeleton placeholder)

Проблем: Пользователь видит пустой экран во время загрузки данных. Скелетоны улучшают восприятие (perceived performance).

Промт:

Напиши компонент SkeletonBox для React Native, который рисует прямоугольник с анимированной пульсацией (прозрачность меняется от 0.2 до 0.8). Пропсы: width, height, borderRadius. Используй Animated.loop и Animated.sequence.

Результат:

import React, { useRef, useEffect } from 'react';
import { Animated, ViewStyle } from 'react-native';

interface SkeletonBoxProps {
  width: number | string;
  height: number;
  borderRadius?: number;
}

const SkeletonBox: React.FC<SkeletonBoxProps> = ({ width, height, borderRadius = 4 }) => {
  const pulseAnim = useRef(new Animated.Value(0.2)).current;

  useEffect(() => {
    const pulse = Animated.sequence([
      Animated.timing(pulseAnim, { toValue: 0.8, duration: 800, useNativeDriver: true }),
      Animated.timing(pulseAnim, { toValue: 0.2, duration: 800, useNativeDriver: true }),
    ]);
    Animated.loop(pulse).start();
  }, []);

  const animatedStyle: Animated.WithAnimatedObject<ViewStyle> = {
    width: width as any,
    height,
    borderRadius,
    backgroundColor: '#E1E9EE',
    opacity: pulseAnim,
  };

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

export default SkeletonBox;

Вывод: Классический скелетон за 30 секунд. Комбинируй несколько блоков для имитации макета.

8. Работа с AsyncStorage (сохранение токена)

Проблем: Нужно сохранять JWT токен локально. Используем @react-native-async-storage/async-storage.

Промт:

Напиши кастомные функции для работы с AsyncStorage: setItem(key, value), getItem(key), removeItem(key). Значения сериализуй через JSON.stringify/parse. Обработай ошибки. На TypeScript. Покажи пример сохранения и чтения токена.

Результат:

import AsyncStorage from '@react-native-async-storage/async-storage';

const STORAGE_KEYS = {
  AUTH_TOKEN: '@auth_token',
} as const;

async function setItem<T>(key: string, value: T): Promise<void> {
  try {
    await AsyncStorage.setItem(key, JSON.stringify(value));
  } catch (e) {
    console.error('Storage set error', e);
  }
}

async function getItem<T>(key: string): Promise<T | null> {
  try {
    const raw = await AsyncStorage.getItem(key);
    return raw ? (JSON.parse(raw) as T) : null;
  } catch (e) {
    console.error('Storage get error', e);
    return null;
  }
}

async function removeItem(key: string): Promise<void> {
  try {
    await AsyncStorage.removeItem(key);
  } catch (e) {
    console.error('Storage remove error', e);
  }
}

export { STORAGE_KEYS, setItem, getItem, removeItem };

Вывод: Типизированная обёртка — безопасно и удобно. Меньше бойлерплейта в каждом экране.

9. i18n для мультиязычности (i18next + react-i18next)

Проблем: Нужно быстро подключить локализацию с переключением языка. Промт генерирует конфиг за секунду.

Промт:

Настрой i18next для React Native. Покажи код инициализации с ресурсами для 'en' и 'ru' (по 3 строки), компонент с useTranslation и кнопку переключения языка. Используй react-i18next. Не забудь про languageDetector (можно заглушку).

Результат:

// i18n.ts
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';

i18n.use(initReactI18next).init({
  resources: {
    en: { translation: { welcome: 'Welcome', logout: 'Logout', settings: 'Settings' } },
    ru: { translation: { welcome: 'Добро пожаловать', logout: 'Выйти', settings: 'Настройки' } },
  },
  lng: 'en',
  fallbackLng: 'en',
  interpolation: { escapeValue: false },
});

export default i18n;

// В компоненте:
import React from 'react';
import { Button, Text, View } from 'react-native';
import { useTranslation } from 'react-i18next';

const SettingsScreen: React.FC = () => {
  const { t, i18n } = useTranslation();
  const toggleLang = () => i18n.changeLanguage(i18n.language === 'en' ? 'ru' : 'en');

  return (
    <View>
      <Text>{t('settings')}</Text>
      <Button title={t('logout')} onPress={() => {}} />
      <Button title="Switch language" onPress={toggleLang} />
    </View>
  );
};

Вывод: Полный рабочий скелет за один промт. Останется добавить реальные переводы.

10. Обработка deep linking через React Navigation

Проблем: Настроить универсальные ссылки (Universal Links / App Links) без чтения всей документации.

Промт:

Настрой конфигурацию deep linking для React Navigation. Приложение имеет Stack с экранами Home и Details (параметр itemId). Пропиши linking config с префиксом 'myapp://' и путь '/details/:itemId'. Покажи код подключения в NavigationContainer. Используй TypeScript.

Результат:

import { LinkingOptions } from '@react-navigation/native';
import { RootStackParamList } from './types';

const linking: LinkingOptions<RootStackParamList> = {
  prefixes: ['myapp://', 'https://myapp.com'],
  config: {
    screens: {
      Home: '',
      Details: 'details/:itemId',
    },
  },
};

// В App.tsx:
<NavigationContainer linking={linking}>
  {/* ... */}
</NavigationContainer>

Вывод: Минимальная настройка — и приложение реагирует на ссылки. Тестируй через npx uri-scheme open myapp://details/42 --ios.

Заключение

Все 10 промтов я использую в ежедневной работе. Они покрывают 80% типовых задач — от UI до интеграций. Сохрани эту статью в закладки, или, ещё лучше, скопируй промты в свой инструмент AI. А если хочешь больше таких шпаргалок — подпишись на блог Asibiont, чтобы не пропустить продолжение.

← Все статьи

Комментарии

Читайте также

Как обезопасить свою музыкальную карьеру: Как курс музыки и аудиопроизводства от Asibiont готовит вас к 2026 году и далее

26 июля 2026

10 промтов для маркетинга и копирайтинга: посты, письма, лендинги и A/B тесты

26 июля 2026

Как подключить 3D-принтер к AI-агенту: интеграция Marlin и Klipper с ASI Biont

26 июля 2026

Как я написал свой первый драйвер для Linux на Rust: опыт курса «Операционные системы и системное программирование» на asibiont.com

26 июля 2026

Крестьянская война в Германии (German Peasants' War): как vibe coding превращает историю в интерактивный опыт

26 июля 2026

Кибербезопасность в 2026: почему курс Asibiont с AI-обучением — ваш шанс войти в профессию с доходом от $150K

26 июля 2026

10 промтов для автоматизации рабочих процессов в Make, n8n и Zapier

26 июля 2026

Является ли курс по стратегическому консалтингу кратчайшим путем в McKinsey, BCG и Bain в 2026 году?

26 июля 2026

Ваш AI-агент не понимает код: он лишь уверенно угадывает — как SLICER меняет подход к генерации

26 июля 2026