react-native-specialist について
React Native 開発者向けに、新アーキテクチャ、ネイティブモジュール、Expo のワークフローを扱うスキルです。アーキテクチャ選定、ネイティブ連携、パフォーマンス改善、トラブルシューティングを案内します。
主な機能
- 01新アーキテクチャのガイダンス
- 02TurboModules と Fabric の手順
- 03Expo と EAS の設定ガイダンス
- 04ネイティブクラッシュとブリッジの調査
- 05性能・アーキテクチャのチェックリスト
活用シーン
- 01旧 Bridge からのアプリ移行
- 02カスタムネイティブモジュールの作成
- 03Expo のビルド・更新ワークフロー設定
- 04描画やメモリーの問題調査
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ 404kidwiz/ claude-supercode-skills --skill react-native-specialistインストール後、Claude Code で/react-native-specialistを入力して読み込まれたか確認します。
詳細
React Native スペシャリスト
目的
「New Architecture」(Fabric/TurboModules)、JSI、Expo のワークフローを専門とする、React Native 開発の専門知識を提供します。カスタムネイティブモジュールと最適化された JavaScript からネイティブへのブリッジを使用して、高性能なクロスプラットフォームのモバイルアプリケーションを構築します。
使用する場面
- New Architecture を使用して高性能な React Native アプリを構築する
- カスタムの Native Module や View Manager(TurboModules/Fabric)を作成する
- Expo のパイプライン(EAS Build、Updates、Config Plugins)を設定する
- ネイティブクラッシュ(Xcode/Android Studio)やブリッジのボトルネックをデバッグする
- Old Architecture(Bridge)から New Architecture(JSI)に移行する
- 複雑なネイティブ SDK(マップ、WebRTC、Bluetooth)を統合する
例
例 1:New Architecture への移行
シナリオ: Bridge から Fabric/TurboModules に、大規模な本番アプリを移行します。
実装:
- New Architecture のフラグを段階的に有効化しました
- Native Module を TurboModules に変換しました
- 複雑な UI 向けに Fabric コンポーネントを実装しました
- Codegen を使用してネイティブブリッジのコードを生成しました
- New Architecture を有効にして徹底的にテストしました
結果:
- UI のレンダリングが 40% 高速化
- バンドルサイズが 30% 縮小
- ネイティブとの境界をまたぐ型安全性が向上
- クラッシュレポートとデバッグが改善
例 2:カスタム Native Module
シナリオ: フィットネスアプリに Bluetooth Low Energy を統合する必要があります。
実装:
- TypeScript の Native Module インターフェースを作成しました
- ネイティブコード(iOS は Swift、Android は Kotlin)を実装しました
- クロスプラットフォームでアクセスできるように RNTurboModule を公開しました
- 適切なメモリ管理とライフサイクル処理を追加しました
- 包括的なエラー処理を実装しました
結果:
- BLE の操作が両プラットフォームでシームレスに動作
- 型安全なブリッジにより実行時エラーを防止
- 従来のネイティブモジュールよりコード量を 50% 削減
- RN のアップグレード後も保守可能
例 3:パフォーマンスの最適化
シナリオ: アプリでスクロールのカクつきやメモリの問題が発生しています。
実装:
- Hermes エンジンを有効化しました
- FlatList を FlashList に置き換えました
- メモ化(useMemo、useCallback)を実装しました
- 画像や負荷の高いコンポーネントに遅延読み込みを追加しました
- ネイティブブリッジの通信を最適化しました
結果:
- スクロールが安定して 60fps で動作
- メモリ使用量を 40% 削減
- アプリの起動時間を 35% 短縮
- クラッシュ率を 60% 削減
ベストプラクティス
アーキテクチャ
- New Architecture:Fabric/TurboModules を有効にして使用します
- Native Modules:型安全性のために Codegen を使用します
- ナビゲーション:React Navigation または Expo Router を使用します
- 状態管理:適切なソリューション(Zustand、Redux)を選択します
パフォーマンス
- Hermes:起動と実行時のパフォーマンス向上のために有効にします
- メモ化:useMemo、useCallback、React.memo を使用します
- リスト:大規模なリストには FlashList を使用します
- 画像:適切に遅延読み込みとキャッシュを行います
ネイティブ統合
- ライフサイクル管理:アプリの状態変化を処理します
- エラーバウンダリ:ネイティブエラーを適切に捕捉します
- 権限:適切にリクエストし、処理します
- テスト:定期的に両プラットフォームでテストします
開発
- Expo ワークフロー:開発を迅速化するために Expo を使用します
- EAS Build:CI/CD ビルドに使用します
- Updates:OTA アップデートには EAS Update を使用します
- TypeScript:すべてのコードに使用します
2. 意思決定フレームワーク
アーキテクチャの選択
Which architecture to use?
│
├─ **New Architecture (Default for 0.76+)**
│ ├─ **TurboModules:** Lazy-loaded native modules (Sync/Async).
│ ├─ **Fabric:** C++ Shadow Tree for UI (No bridge serialization).
│ ├─ **Codegen:** Type-safe spec for Native <-> JS communication.
│ └─ **Bridgeless Mode:** Removes the legacy bridge entirely.
│
└─ **Old Architecture (Legacy)**
├─ **Bridge:** Async JSON serialization (Slow for large data).
└─ **Maintenance:** Only for unmigrated legacy libraries.
Expo と CLI の比較
| 機能 | Expo(Managed) | React Native CLI(Bare) |
|---|---|---|
| セットアップ | 即時(create-expo-app) | 複雑(JDK、Xcode、Pods) |
| ネイティブコード | Config Plugins(ネイティブファイルを自動変更) | ファイルを直接編集(AppDelegate.m) |
| アップグレード | npx expo install --fix(安定したセット) | 差分を手動で確認(Upgrade Helper) |
| ビルド | EAS Build(クラウド) | ローカルまたは CI(Fastlane) |
| アップデート | EAS Update(OTA) | CodePush(Microsoft) |
パフォーマンス戦略
- JSI: C++ を直接呼び出します。JSON のシリアライズはありません。
- Reanimated: UI スレッドでアニメーションを実行します(Worklets)。
- FlashList: ビューを再利用します(FlatList を置き換えます)。
- Hermes: バイトコードを事前コンパイルします(起動が瞬時になります)。
危険な兆候 → mobile-developer(ネイティブ)にエスカレーション:
- React Native エンジンのコア(C++)を変更する
- 原因不明の ProGuard/R8 クラッシュをデバッグする
- 低レベルの Metal/OpenGL レンダラーを一から作成する
3. コアワークフロー
ワークフロー 1:TurboModule の作成(新アーキテクチャ)
目標: JSI を介してネイティブのバッテリー残量に同期的にアクセスします。
手順:
-
仕様を定義する(
NativeBattery.ts)import type { TurboModule } from 'react-native'; import { TurboModuleRegistry } from 'react-native'; export interface Spec extends TurboModule { getBatteryLevel(): number; } export default TurboModuleRegistry.getEnforcing<Spec>('RTNBattery'); -
コードを生成する
yarn codegenを実行します。C++ インターフェースが生成されます。
-
iOS を実装する(
RTNBattery.mm)- (NSNumber *)getBatteryLevel { [UIDevice currentDevice].batteryMonitoringEnabled = YES; return @([UIDevice currentDevice].batteryLevel); } - (std::shared_ptr<facebook::react::TurboModule>)getTurboModule: (const facebook::react::ObjCTurboModule::InitParams &)params { return std::make_shared<facebook::react::NativeBatterySpecJSI>(params); } -
Android を実装する(
BatteryModule.kt)class BatteryModule(context: ReactApplicationContext) : NativeBatterySpec(context) { override fun getName() = "RTNBattery" override fun getBatteryLevel(): Double { val manager = context.getSystemService(Context.BATTERY_SERVICE) as BatteryManager return manager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY).toDouble() } }
ワークフロー 3:Reanimated Worklets
目標: UI スレッドで 60fps のドラッグジェスチャーを実現します。
手順:
-
セットアップ
import { useSharedValue, useAnimatedStyle, withSpring } from 'react-native-reanimated'; import { GestureDetector, Gesture } from 'react-native-gesture-handler'; -
実装
function Ball() { const offset = useSharedValue({ x: 0, y: 0 }); const gesture = Gesture.Pan() .onUpdate((e) => { // UI スレッドで実行されます offset.value = { x: e.translationX, y: e.translationY }; }) .onEnd(() => { offset.value = withSpring({ x: 0, y: 0 }); // 元の位置に戻る }); const style = useAnimatedStyle(() => ({ transform: [{ translateX: offset.value.x }, { translateY: offset.value.y }] })); return ( <GestureDetector gesture={gesture}> <Animated.View style={[styles.ball, style]} /> </GestureDetector> ); }
5. アンチパターンと注意点
❌ アンチパターン 1:「ブリッジをまたぐ」アニメーション
例:
useNativeDriver: falseを指定してAnimated.timingを使用するuseEffectでレイアウトを計算し、setStateを呼び出す
問題点:
- JS スレッドで実行されます。JS がデータを取得していてビジー状態の場合、フレームが落ちます。
推奨される方法:
- Reanimated または
useNativeDriver: trueを使用します。
❌ アンチパターン 2:Hermes を使わない大きなバンドル
例:
- Android で JSC(JavaScriptCore)を使用する
- 起動に 5 秒かかる
問題点:
- JSC は実行時に JS を解析します。Hermes は事前コンパイルされたバイトコードを実行します。
推奨される方法:
podfile/build.gradleで Hermes を有効にします(新しい Expo ではデフォルトです)。
❌ アンチパターン 3:レンダー中のスタイル定義
例:
style={{ width: 100, height: 100 }}
問題点:
- レンダーのたびに新しいオブジェクトが作成され、差分計算が発生します。
推奨される方法:
- コンポーネントの外で
StyleSheet.createまたはconst style = { ... }を使用します。
7. 品質チェックリスト
パフォーマンス:
- Hermes: 有効化します。
- メモ化: コストの高い props には
useMemo/useCallbackを使用します。 - リスト:
FlatListの代わりにFlashListを使用します。
アーキテクチャ:
- 新アーキテクチャ: Fabric/TurboModules を有効化します(ライブラリが対応している場合)。
- ナビゲーション: ネイティブ画面を使用します(React Navigation / Expo Router)。
ネイティブ:
- 権限: 適切に処理します(拒否されてもクラッシュしないようにします)。
- アップグレード: React Native のバージョンを新しい状態に保ちます(マイナーバージョンで 2 つ以内)。
アンチパターン
アーキテクチャのアンチパターン
- ブリッジの過剰使用:旧アーキテクチャのブリッジを多用しています — 新アーキテクチャへ移行します
- 不要なネイティブ実装:純粋な JS ロジックをネイティブでラップしています — シンプルに保ちます
- 状態管理の乱立:複数の競合する状態管理ソリューションを使用しています — 1 つに統一します
- ナビゲーションのネスト:ナビゲーターが深くネストしています — ナビゲーションを浅く保ちます
パフォーマンスのアンチパターン
- すべてを再レンダリング:React.memo や最適化を使用していません — コンポーネントの再レンダリングを最適化します
- FlatList の乱用:すべてのリストに FlatList を使用しています — 適切なリストコンポーネントを使用します
- メモリーリーク:サブスクリプションをクリーンアップしていません — useEffect でクリーンアップします
- ブリッジのボトルネック:ブリッジ通信が多すぎます — ブリッジをまたぐ呼び出しを最小限に抑えます
開発のアンチパターン
- 本番環境でのデバッグモード:本番用にビルドしていません — 本番ビルドを必ずテストします
- Hermes を使用しない:Hermes エンジンを使用していません — パフォーマンス向上のため有効化します
- バンドルが大きい:バンドルを最適化していません — RAM バンドルと圧縮を使用します
- 手動リンク:不要なのにネイティブのリンクを手動で行っています — 自動リンクを使用します
テストのアンチパターン
- E2E テストがない:ユニットテストのみです — Maestro または Detox のテストを追加します
- プラットフォーム条件分岐:プラットフォームのチェックが多すぎます — プラットフォーム間の違いを抽象化します
- 寸法のハードコード:ピクセル値を固定しています — 相対サイズを使用します
- testID がない:アクセシビリティ識別子がありません — テスト用に testID を追加します