React Native アプリ開発ガイド 2026:本番環境向けアプリ構築と面接対策

2026年のReact Native本番開発を解説。Expo SDK 56、EAS Build、Hermes V1、New Architectureを活用したアプリ構築と、React Native開発者向け面接質問を網羅します。

React Native アプリ開発ガイド 2026:本番環境向けアプリ構築と面接対策

2026年のReact Nativeアプリ開発は、New Architecture、Expo SDK 56、そして過去1年で大きく成熟した本番対応ツールを中心に展開されています。本ガイドでは、本番アプリを構築するための実践的なワークフローと、経験豊富なReact Native開発者を見分けるための面接質問について解説します。

2026年の本番スタック

推奨される本番スタック:EAS Buildを備えたExpo SDK 56、React Native 0.85以上、Hermes V1エンジン、そしてデフォルトで有効なNew Architecture。SDK 55と比較して、iOSでは16%、Androidでは60%のビルド時間短縮を実現しています。

本番対応React Nativeプロジェクトのセットアップ

2026年に新しいReact Nativeプロジェクトを開始する場合、Expo(推奨)またはBare React Nativeのいずれかを選択することになります。Expoは初心者向けのラッパーから進化し、ほとんどの本番アプリにおいてReact Nativeチームが公式に推奨する選択肢となっています。

bash
# Create a new Expo project with SDK 56
npx create-expo-app@latest my-production-app
cd my-production-app

# Verify the New Architecture is enabled (default since RN 0.76)
npx expo config --type introspect | grep newArchEnabled

New ArchitectureにはFabric、TurboModules、JSIが含まれており、複雑なアプリでパフォーマンスのボトルネックとなっていた非同期JSONブリッジを排除しています。JavaScriptがネイティブモジュールを同期的に呼び出せるようになり、タイミングに関するバグの一カテゴリ全体が解消されました。

app.json - Production configurationtypescript
{
  "expo": {
    "name": "MyProductionApp",
    "slug": "my-production-app",
    "version": "1.0.0",
    "newArchEnabled": true, // Default in SDK 56
    "android": {
      "package": "com.company.myproductionapp",
      "adaptiveIcon": {
        "foregroundImage": "./assets/adaptive-icon.png",
        "backgroundColor": "#ffffff"
      }
    },
    "ios": {
      "bundleIdentifier": "com.company.myproductionapp",
      "supportsTablet": true
    },
    "plugins": [
      "expo-router"
    ]
  }
}

Expo RouterはNext.jsに似たファイルベースのルーティングを提供し、ナビゲーションの標準となっています。/appディレクトリ構造がルートに直接マッピングされます。

Hermes V1エンジンとJavaScriptパフォーマンス

Hermes V1はReact Native 0.84でデフォルトのJavaScriptエンジンとして出荷され、JavaScriptCoreとレガシーHermesの両方を置き換えました。新しいコンパイラと仮想マシンは、より高速なバイトコード実行、より小さなメモリフットプリント、そしてより良好なガベージコレクションの一時停止分布を実現しています。

typescript
// Performance monitoring with Hermes V1
// HermesInternal is available globally when running on Hermes
declare global {
  var HermesInternal: {
    getRuntimeProperties: () => Record<string, unknown>;
    enableSamplingProfiler: () => void;
    disableSamplingProfiler: () => string;
  } | undefined;
}

export function checkHermesStatus(): boolean {
  const isHermes = typeof HermesInternal === 'object' && HermesInternal !== null;

  if (isHermes && __DEV__) {
    const props = HermesInternal.getRuntimeProperties();
    console.log('Hermes version:', props['OSS Release Version']);
    console.log('Bytecode version:', props['Bytecode Version']);
  }

  return isHermes;
}

Hermes V1はビルドプロセス中にJavaScriptをバイトコードにプリコンパイルします。これにより、アプリの起動時間の大部分を占めるJavaScriptの解析が実行時に排除されます。本番ビルドでは、JSCと比較してTime to Interactiveが10〜30%高速になります。

EAS Buildと最適化されたコンパイルによる構築

EAS Buildはキャッシング、署名、配布機能を備えたクラウド上で本番ビルドを処理します。SDK 56では、iOS用のExpoモジュール向けプリビルトXCFrameworkと、実行時のリフレクションを排除するAndroid用Kotlinコンパイラプラグインが導入されました。

eas.json - Production build configurationtypescript
{
  "cli": {
    "version": ">= 15.0.0"
  },
  "build": {
    "development": {
      "developmentClient": true,
      "distribution": "internal",
      "ios": {
        "simulator": true
      }
    },
    "preview": {
      "distribution": "internal",
      "ios": {
        "resourceClass": "m-medium"
      },
      "android": {
        "buildType": "apk"
      }
    },
    "production": {
      "ios": {
        "resourceClass": "m-large"
      },
      "android": {
        "buildType": "app-bundle"
      },
      "env": {
        "EXPO_USE_PRECOMPILED_MODULES": "1"
      }
    }
  },
  "submit": {
    "production": {}
  }
}

本番アプリのビルド方法:

bash
# Build for iOS App Store
eas build --platform ios --profile production

# Build for Google Play
eas build --platform android --profile production

# Submit to stores after build
eas submit --platform all

Android向けのプリコンパイルヘッダー機能(expo-build-propertiesのusePrecompiledHeaders)により、Expoのベンチマークではcmakeのコンパイル時間が17分から6分に短縮されました。

React Nativeの面接対策はできていますか?

インタラクティブなシミュレーター、flashcards、技術テストで練習しましょう。

状態管理とデータフェッチパターン

本番React Nativeアプリでは通常、サーバー状態にはTanStack Queryを、クライアント状態にはZustandまたはJotaiを組み合わせて使用します。この分離によりコードベースの予測可能性が維持され、ほとんどのユースケースでReduxの複雑さを回避できます。

hooks/useProducts.tstypescript
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { api } from '@/lib/api';
import type { Product } from '@/types';

// Query key factory for type-safe cache management
export const productKeys = {
  all: ['products'] as const,
  lists: () => [...productKeys.all, 'list'] as const,
  list: (filters: ProductFilters) => [...productKeys.lists(), filters] as const,
  details: () => [...productKeys.all, 'detail'] as const,
  detail: (id: string) => [...productKeys.details(), id] as const,
};

export function useProducts(filters: ProductFilters) {
  return useQuery({
    queryKey: productKeys.list(filters),
    queryFn: () => api.products.list(filters),
    staleTime: 5 * 60 * 1000, // 5 minutes
    gcTime: 30 * 60 * 1000,   // 30 minutes (formerly cacheTime)
  });
}

export function useCreateProduct() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: (data: CreateProductInput) => api.products.create(data),
    onSuccess: () => {
      // Invalidate list queries to refetch
      queryClient.invalidateQueries({ queryKey: productKeys.lists() });
    },
  });
}

オフラインファースト機能については、TanStack QueryとWatermelonDBまたはexpo-sqliteによる組み込みSQLiteサポートを組み合わせます:

lib/offline-sync.tstypescript
import * as SQLite from 'expo-sqlite';
import NetInfo from '@react-native-community/netinfo';

const db = SQLite.openDatabaseSync('app.db');

export async function initializeOfflineStorage() {
  await db.execAsync(`
    CREATE TABLE IF NOT EXISTS pending_mutations (
      id TEXT PRIMARY KEY,
      type TEXT NOT NULL,
      payload TEXT NOT NULL,
      created_at INTEGER NOT NULL
    );
  `);
}

export async function queueMutation(type: string, payload: object) {
  const id = crypto.randomUUID();
  await db.runAsync(
    'INSERT INTO pending_mutations (id, type, payload, created_at) VALUES (?, ?, ?, ?)',
    [id, type, JSON.stringify(payload), Date.now()]
  );
}

export async function syncPendingMutations() {
  const state = await NetInfo.fetch();
  if (!state.isConnected) return;

  const pending = await db.getAllAsync<PendingMutation>(
    'SELECT * FROM pending_mutations ORDER BY created_at ASC'
  );

  for (const mutation of pending) {
    try {
      await processMutation(mutation);
      await db.runAsync('DELETE FROM pending_mutations WHERE id = ?', [mutation.id]);
    } catch (error) {
      console.error('Sync failed for mutation:', mutation.id);
      break; // Stop on first failure to maintain order
    }
  }
}

React Native Reanimated 4によるアニメーションシステム

React Native 0.85ではNew Architectureと連携する新しいアニメーションバックエンドが導入されました。Reanimated 4はこれを最大限に活用し、JSブリッジを経由せずにUIスレッドでアニメーションを実行します。

components/AnimatedCard.tsxtypescript
import Animated, {
  useSharedValue,
  useAnimatedStyle,
  withSpring,
  withTiming,
  interpolate,
  Extrapolation,
} from 'react-native-reanimated';
import { Gesture, GestureDetector } from 'react-native-gesture-handler';

const SWIPE_THRESHOLD = 120;

export function SwipeableCard({ onSwipe, children }: SwipeableCardProps) {
  const translateX = useSharedValue(0);
  const opacity = useSharedValue(1);

  const panGesture = Gesture.Pan()
    .onUpdate((event) => {
      translateX.value = event.translationX;
    })
    .onEnd((event) => {
      if (Math.abs(event.translationX) > SWIPE_THRESHOLD) {
        const direction = event.translationX > 0 ? 'right' : 'left';
        translateX.value = withTiming(
          direction === 'right' ? 500 : -500,
          { duration: 200 }
        );
        opacity.value = withTiming(0, { duration: 200 }, () => {
          onSwipe(direction);
        });
      } else {
        translateX.value = withSpring(0, {
          damping: 15,
          stiffness: 150,
        });
      }
    });

  const animatedStyle = useAnimatedStyle(() => ({
    transform: [
      { translateX: translateX.value },
      {
        rotate: `${interpolate(
          translateX.value,
          [-200, 0, 200],
          [-15, 0, 15],
          Extrapolation.CLAMP
        )}deg`,
      },
    ],
    opacity: opacity.value,
  }));

  return (
    <GestureDetector gesture={panGesture}>
      <Animated.View style={animatedStyle}>
        {children}
      </Animated.View>
    </GestureDetector>
  );
}

workletディレクティブ(Reanimated 4ではuseAnimatedStyleに渡される関数に対して暗黙的に適用)により、アニメーションロジックがUIスレッドで実行されることが保証されます。これにより、対応デバイスで一貫した120Hzのリフレッシュレートを実現します。

React Native開発者向け面接質問

2026年のReact Native職の技術面接では、New Architecture、パフォーマンス最適化、本番デプロイメントに重点が置かれています。特定のトピックを練習するには、React Native面接質問をご覧ください。

New Architectureで何が変わり、なぜ重要なのか?

New Architectureは非同期JSONブリッジをJSI(JavaScript Interface)に置き換え、JavaScriptとネイティブコード間の同期通信を可能にしました。コアを形成する3つのコンポーネント:

  1. JSI:JavaScriptがネイティブオブジェクトへの参照を保持し、そのメソッドを直接呼び出せるようにするC++レイヤー
  2. Fabric:同期レイアウト測定と並行レンダリングをサポートする新しいレンダリングシステム
  3. TurboModules:遅延ロードされ、ブリッジではなくJSIを通じて通信するネイティブモジュール

実際の影響:一般的なアプリでUIスレッドの競合が10〜30%減少しました。ネイティブモジュールを多用するアプリでは、シリアライゼーションのオーバーヘッドが排除されるため、スレッド間呼び出しのパフォーマンスが最大3倍向上します。

Hermes V1とJavaScriptCoreの違いは?

Hermes V1はビルド時にJavaScriptをバイトコードにプリコンパイルし、実行時の解析ステップを排除します。主な違い:

  • 起動時間:Hermesは解析をスキップし、Time to Interactiveを10〜30%短縮
  • メモリ:最適化されたバイトコード表現により、ベースラインのメモリ使用量が低下
  • デバッグ:HermesはChrome DevTools Protocolをネイティブで使用し、JSCはカスタムアダプターが必要だった
  • ガベージコレクション:Hermesは一時停止時間が短い世代別GCを使用

トレードオフ:Hermesは歴史的に計算集約的なコードでピーク実行速度が遅かったが、V1でこのギャップは大幅に縮小されました。

React NativeでuseCallback、useMemo、React.memoの違いを説明してください

3つともメモ化ツールですが、目的が異なります:

typescript
// useCallback: memoizes a function reference
const handlePress = useCallback(() => {
  navigation.navigate('Detail', { id: item.id });
}, [item.id, navigation]);

// useMemo: memoizes a computed value
const sortedItems = useMemo(() => {
  return items.slice().sort((a, b) => a.price - b.price);
}, [items]);

// React.memo: memoizes a component's render output
const ProductCard = React.memo(function ProductCard({ product, onPress }: Props) {
  return (
    <Pressable onPress={onPress}>
      <Text>{product.name}</Text>
    </Pressable>
  );
});

React Nativeでは、React.memoはFlatListでレンダリングされるリストアイテムに特に重要です。これがないと、親の状態が変更されるたびにすべてのアイテムが再レンダリングされ、スクロール中にフレームドロップが発生します。

本番React Nativeアプリでディープリンクをどのように処理しますか?

ディープリンクには複数のレイヤーでの設定が必要です:ネイティブURLスキーム、ユニバーサル/アプリリンク、そしてJavaScriptルーター。

app.json - Configure URL schemestypescript
{
  "expo": {
    "scheme": "myapp",
    "ios": {
      "associatedDomains": ["applinks:myapp.com"]
    },
    "android": {
      "intentFilters": [
        {
          "action": "VIEW",
          "autoVerify": true,
          "data": [
            {
              "scheme": "https",
              "host": "myapp.com",
              "pathPrefix": "/product"
            }
          ],
          "category": ["BROWSABLE", "DEFAULT"]
        }
      ]
    }
  }
}

Expo RouterはアプリディレクトリがURLパスと一致する場合、解析を自動的に処理します。カスタム処理の場合:

app/_layout.tsxtypescript
import { useURL } from 'expo-linking';
import { useEffect } from 'react';
import { router } from 'expo-router';

export default function RootLayout() {
  const url = useURL();

  useEffect(() => {
    if (url) {
      const parsed = parseDeepLink(url);
      if (parsed.requiresAuth && !isAuthenticated) {
        // Store intended destination, redirect to login
        router.replace('/login');
      }
    }
  }, [url]);

  return <Slot />;
}

ユニバーサルリンク(iOS)とApp Links(Android)にはサーバーサイドの設定が必要です:それぞれルートドメインから提供されるapple-app-site-associationファイルとassetlinks.jsonファイルです。

今すぐ練習を始めましょう!

面接シミュレーターと技術テストで知識をテストしましょう。

2026年のReact Native開発における重要ポイント

  • New Architectureは必須:旧ブリッジはReact Native 0.82で無効化され、npmパッケージの85%が新アーキテクチャをサポート
  • EAS Buildを備えたExpo SDK 56は本番への最速の道筋を提供し、プリビルトモジュールによりiOSビルド時間を16%、AndroidのCMakeコンパイルを60%短縮
  • Hermes V1は設定不要でデフォルトエンジンとなり、JSCと比較して10〜30%高速な起動を実現
  • TanStack Queryと軽量クライアント状態ライブラリ(Zustand/Jotai)は、Reduxの複雑さなしにほとんどの本番データ管理ニーズをカバー
  • 新しいアニメーションバックエンドを備えたReanimated 4は、UIスレッド上で完全に実行することで120Hzアニメーションを実現
  • 面接準備はJSIの仕組み、Fabricレンダリング、Hermesによるパフォーマンスプロファイリング、EASによる本番デプロイに集中すべき
今日のチャレンジ

React Native のバグを見つけられますか

実際のコード、隠れたバグ、1日1回。アカウントなしで試せます。

Anthony Fillion-Maillet

執筆

Anthony Fillion-Maillet

SharpSkill 創業者

10 年以上フルスタック開発に携わっています。SharpSkill を運営し、ここで公開される内容に責任を負っています。

2026年9月14日 更新

共有

関連記事