mcpField
R
react-native-expo

react-native-expo

github.com/ovachiever开发56104 次安装50 周前更新
代码仓库

关于 react-native-expo

react-native-expo 是面向 Expo SDK 52+ 和较新 React Native 版本的开发与升级技能,涵盖架构变更、迁移注意事项以及开发和调试流程。

主要功能

  1. 01Expo 项目创建与启动
  2. 02新架构迁移指导
  3. 03React 19 变更说明
  4. 04React Native DevTools 调试
  5. 05常见升级问题排查

适用场景

  1. 01创建 Expo 应用
  2. 02升级旧版 React Native 项目
  3. 03排查新架构兼容问题
  4. 04在 DevTools 中查看日志

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/ovachiever/droid-tings --skill react-native-expo

安装后在 Claude Code 中输入/react-native-expo确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

README.md
.claude-plugin/
plugin.json
assets/
css-features-cheatsheet.md
example-template.txt
new-arch-decision-tree.md
references/
example-reference.md
expo-sdk-52-breaking.md
new-architecture-errors.md
react-19-migration.md
scripts/
check-rn-version.sh
example-script.sh

详细介绍

React Native Expo(0.76-0.82+ / SDK 52+)

状态:已可用于生产环境 最后更新:2025-11-22 依赖项:Node.js 18+、Expo CLI 最新版本:[email protected]、expo@~52.0.0、[email protected]


快速入门(15 分钟)

1. 创建新的 Expo 项目(RN 0.76+)
# Create new Expo app with React Native 0.76+
npx create-expo-app@latest my-app

cd my-app

# Install latest dependencies
npx expo install react-native@latest expo@latest

重要原因:

  • Expo SDK 52+ 使用默认启用新架构的 React Native 0.76+
  • React Native 0.82+ 强制要求启用新架构(无法禁用)
  • Hermes 是唯一受支持的 JavaScript 引擎(Expo Go 已移除 JSC)
2. 确认已启用新架构
# Check if New Architecture is enabled (should be true by default)
npx expo config --type introspect | grep newArchEnabled

重要提示:

  • React Native 0.82+ 要求使用新架构——旧架构已从代码库中彻底移除
  • 如果从 0.75 或更早版本迁移,请先升级到 0.76-0.81,以使用互操作层
  • 在 0.82+ 中切勿尝试禁用新架构(否则构建会失败)
3. 启动开发服务器
# Start Expo dev server
npx expo start

# Press 'i' for iOS simulator
# Press 'a' for Android emulator
# Press 'j' to open React Native DevTools (NOT Chrome debugger!)

重要提示:

  • 旧版 Chrome 调试器已在 0.79 中移除,请改用 React Native DevTools
  • Metro 终端不再输出 console.log(),请使用 DevTools Console
  • 键盘快捷键 'a'/'i' 可在 CLI 中使用,不能在 Metro 终端中使用

重大破坏性变更(2024 年 12 月起)

🔴 新架构成为强制要求(0.82+)

变更内容:

  • 0.76-0.81:默认启用新架构,旧架构已冻结(不再添加新功能)
  • 0.82+:旧架构已从代码库中彻底移除

影响:

# This will FAIL in 0.82+:
# gradle.properties (Android)
newArchEnabled=false  # ❌ Ignored, build fails

# iOS
RCT_NEW_ARCH_ENABLED=0  # ❌ Ignored, build fails

迁移路径:

  1. 先升级到 0.76-0.81(如果当前使用 0.75 或更早版本)
  2. 在启用新架构的情况下进行测试
  3. 修复不兼容的依赖项(Redux、i18n、CodePush)
  4. 然后升级到 0.82+
🔴 移除 propTypes(React 19 / RN 0.78+)

变更内容: React 19 完全移除了 propTypes。不再进行运行时验证,也不会发出警告——这些设置会被静默忽略。

变更前(旧代码):

import PropTypes from 'prop-types';

function MyComponent({ name, age }) {
  return <Text>{name} is {age}</Text>;
}

MyComponent.propTypes = {  // ❌ Silently ignored in React 19
  name: PropTypes.string.isRequired,
  age: PropTypes.number
};

变更后(使用 TypeScript):

type MyComponentProps = {
  name: string;
  age?: number;
};

function MyComponent({ name, age }: MyComponentProps) {
  return <Text>{name} is {age}</Text>;
}

迁移:

# Use React 19 codemod to remove propTypes
npx @codemod/react-19 upgrade
🔴 forwardRef 已弃用(React 19)

变更内容: 不再需要 forwardRef——可将 ref 作为普通属性传递。

变更前(旧代码):

import { forwardRef } from 'react';

const MyInput = forwardRef((props, ref) => {  // ❌ Deprecated
  return <TextInput ref={ref} {...props} />;
});

变更后(React 19):

function MyInput({ ref, ...props }) {  // ✅ ref is a regular prop
  return <TextInput ref={ref} {...props} />;
}
🔴 iOS 默认模板改用 Swift(0.77+)

变更内容: 新项目使用 Swift AppDelegate.swift,而非 Objective-C AppDelegate.mm。

旧结构:

ios/MyApp/
├── main.m              # ❌ Removed
├── AppDelegate.h       # ❌ Removed
└── AppDelegate.mm      # ❌ Removed

新结构:

// ios/MyApp/AppDelegate.swift ✅
import UIKit
import React

@main
class AppDelegate: UIResponder, UIApplicationDelegate {
  func application(_ application: UIApplication, ...) -> Bool {
    // App initialization
    return true
  }
}

迁移(0.76 → 0.77): 升级现有项目时,必须添加此行:

// Add to AppDelegate.swift during migration
import React
import ReactCoreModules

RCTAppDependencyProvider.sharedInstance()  // ⚠️ CRITICAL: Must add this!

来源: React Native 0.77 Release Notes

🔴 移除 Metro 日志转发(0.77+)

变更内容: Metro 终端不再输出 console.log() 内容。

变更前(0.76):

# console.log() appeared in Metro terminal
$ npx expo start
> LOG  Hello from app!  # ✅ Appeared here

变更后(0.77+):

# console.log() does NOT appear in Metro terminal
$ npx expo start
# (no logs shown)  # ❌ Removed

# Workaround (temporary, will be removed):
$ npx expo start --client-logs  # Shows logs, deprecated

解决方案: 改用 React Native DevTools Console(在 CLI 中按 'j')。

来源: React Native 0.77 Release Notes

🔴 移除 Chrome 调试器(0.79+)

变更内容: 旧版 Chrome 调试器(chrome://inspect)已移除。请改用 React Native DevTools。

旧方法(已移除):

# ❌ This no longer works:
# Open Dev Menu → "Debug" → Chrome DevTools opens

新方法(0.76+):

# Press 'j' in CLI or Dev Menu → "Open React Native DevTools"
# ✅ Uses Chrome DevTools Protocol (CDP)
# ✅ Reliable breakpoints, watch values, stack inspection
# ✅ JS Console (replaces Metro logs)

限制:

  • 暂不支持第三方扩展(Redux DevTools 等)
  • 网络检查器预计将在 0.83 中推出(2025 年末)

来源: React Native 0.79 Release Notes

🔴 JSC 引擎移至社区维护(0.79+)

变更内容: JavaScriptCore(JSC)已从 React Native 核心移出,Hermes 为默认引擎。

变更前(0.78):

  • 同时捆绑 Hermes 和 JSC
  • Expo Go 中可使用 JSC

变更后(0.79+):

// If you still need JSC (rare):
{
  "dependencies": {
    "@react-native-community/javascriptcore": "^1.0.0"
  }
}

Expo Go:

  • Expo Go(SDK 52+)已完全移除 JSC
  • 仅支持 Hermes

注意: JSC 最终将从 React Native 中彻底移除。

🔴 弃用深层导入(0.80+)

变更内容: 从内部路径导入将导致问题。

变更前(旧代码):

// ❌ Deep imports deprecated
import Button from 'react-native/Libraries/Components/Button';
import Platform from 'react-native/Libraries/Utilities/Platform';

变更后:

// ✅ Import only from 'react-native'
import { Button, Platform } from 'react-native';

来源: React Native 0.80 Release Notes


新功能(2024 年 12 月之后)

CSS 属性(仅适用于 0.77+ 新架构)

React Native 现在支持许多此前仅适用于 Web 的 CSS 属性:

1. display: contents

使元素“不可见”,但保留其子元素在布局中的位置:

<View style={{ display: 'contents' }}>
  {/* This View disappears, but Text still renders */}
  <Text>I'm still here!</Text>
</View>

适用场景: 不应影响布局的包装组件。

2. boxSizing

控制宽度和高度的计算方式:

// Default: padding/border inside box
<View style={{
  boxSizing: 'border-box',  // Default
  width: 100,
  padding: 10,
  borderWidth: 2
  // Total width: 100 (padding/border inside)
}} />

// Content-box: padding/border outside
<View style={{
  boxSizing: 'content-box',
  width: 100,
  padding: 10,
  borderWidth: 2
  // Total width: 124 (100 + 20 padding + 4 border)
}} />
3. mixBlendMode + isolation

像 Photoshop 一样混合图层:

<View style={{ backgroundColor: 'red' }}>
  <View style={{
    mixBlendMode: 'multiply',  // 16 modes available
    backgroundColor: 'blue'
    // Result: purple (red × blue)
  }} />
</View>

// Prevent unwanted blending:
<View style={{ isolation: 'isolate' }}>
  {/* Blending contained within this view */}
</View>

可用模式: multiply、screen、overlay、darken、lighten、color-dodge、color-burn、hard-light、soft-light、difference、exclusion、hue、saturation、color、luminosity

4. outline 属性

不影响布局的视觉轮廓(与 border 不同):

<View style={{
  outlineWidth: 2,
  outlineStyle: 'solid',      // solid | dashed | dotted
  outlineColor: 'blue',
  outlineOffset: 4,           // Space between element and outline
  outlineSpread: 2            // Expand outline beyond offset
}} />

主要区别: 轮廓不会改变元素尺寸,也不会触发布局重新计算。

来源: React Native 0.77 发行说明

Android XML Drawable(0.78+)

使用原生 Android 矢量 Drawable(XML)作为 Image 源:

// Load XML drawable at build time
import MyIcon from './assets/my_icon.xml';

<Image
  source={MyIcon}
  style={{ width: 40, height: 40 }}
/>

// Or with require:
<Image
  source={require('./assets/my_icon.xml')}
  style={{ width: 40, height: 40 }}
/>

优势:

  • 可缩放矢量图形(与分辨率无关)
  • 与 PNG 相比,APK 体积更小
  • 在后台线程解码(性能更佳)

限制:

  • 仅限构建时资源(不支持从网络加载)
  • 仅适用于 Android(iOS 仍使用 SF Symbols 或 PNG)

来源: React Native 0.78 发行说明

React 19 新增 Hook
1. useActionState(替代表单处理模式)
import { useActionState } from 'react';

function MyForm() {
  const [state, submitAction, isPending] = useActionState(
    async (prevState, formData) => {
      // Async form submission
      const result = await api.submit(formData);
      return result;
    },
    { message: '' }  // Initial state
  );

  return (
    <form action={submitAction}>
      <TextInput name="email" />
      <Button disabled={isPending}>
        {isPending ? 'Submitting...' : 'Submit'}
      </Button>
      {state.message && <Text>{state.message}</Text>}
    </form>
  );
}
2. useOptimistic(乐观 UI 更新)
import { useOptimistic } from 'react';

function LikeButton({ postId, initialLikes }) {
  const [optimisticLikes, addOptimisticLike] = useOptimistic(
    initialLikes,
    (currentLikes, amount) => currentLikes + amount
  );

  async function handleLike() {
    addOptimisticLike(1);  // Update UI immediately
    await api.like(postId);  // Then update server
  }

  return (
    <Button onPress={handleLike}>
      ❤️ {optimisticLikes}
    </Button>
  );
}
3. use(在渲染期间读取 Promise/上下文)
import { use } from 'react';

function UserProfile({ userPromise }) {
  // Read promise directly during render (suspends if pending)
  const user = use(userPromise);

  return <Text>{user.name}</Text>;
}

来源: React 19 升级指南

React Native DevTools(0.76+)

打开方式:

  • 在 CLI 中按 j
  • 或打开 Dev Menu →“打开 React Native DevTools”

功能:

  • ✅ 断点可靠(不像旧版 Chrome 调试器)
  • ✅ 监视值、检查调用栈
  • ✅ JS 控制台(替代 Metro 日志)
  • ✅ 基于 Chrome DevTools Protocol(CDP)
  • ⏳ 网络检查器(即将在 0.83 中推出)
  • ❌ 暂不支持第三方扩展

来源: React Native DevTools 公告


已知问题预防

此技能可预防 12 个有记录的问题:

问题 #1:propTypes 被静默忽略

错误: 没有错误——propTypes 只是无法使用 来源: React 19 升级指南 发生原因: React 19 移除了运行时 propTypes 验证 预防方法: 改用 TypeScript,并运行 npx @codemod/react-19 upgrade 将其移除

问题 #2:forwardRef 弃用警告

错误: Warning: forwardRef is deprecated 来源: React 19 升级指南 发生原因: React 19 允许将 ref 作为常规 prop 使用 预防方法: 移除 forwardRef 包装器,直接将 ref 作为 prop 传递

问题 #3:无法禁用新架构(0.82+)

错误: 使用 newArchEnabled=false 时构建失败 来源: React Native 0.82 发行说明 发生原因: 代码库中已完全移除旧架构 预防方法: 升级到 0.82+ 之前迁移到新架构

问题 #4:“未找到 Fabric 组件描述符”

错误: Fabric component descriptor provider not found for component 来源: 新架构迁移指南 发生原因: 组件与新架构(Fabric)不兼容 预防方法: 将库更新到新架构版本,或使用互操作层(0.76-0.81)

问题 #5:“TurboModule 未注册”

错误: TurboModule '[ModuleName]' not found 来源: New Architecture 迁移指南 原因: 原生模块需要支持 New Architecture(TurboModules) 预防: 更新库以支持 TurboModules,或使用互操作层(0.76-0.81)

问题 #6:Swift AppDelegate 缺少 RCTAppDependencyProvider

错误: RCTAppDependencyProvider not found 来源: React Native 0.77 发布说明 原因: 从 Objective-C 模板迁移到 Swift 模板时 预防: 将 RCTAppDependencyProvider.sharedInstance() 添加到 AppDelegate.swift

问题 #7:Metro 日志未显示

错误: console.log() 未在终端中显示 来源: React Native 0.77 发布说明 原因: 0.77 中移除了 Metro 日志转发 预防: 使用 React Native DevTools Console(按 ‘j’),或使用 --client-logs 标志(临时方案)

问题 #8:Chrome 调试器无法使用

错误: Chrome DevTools 无法连接 来源: React Native 0.79 发布说明 原因: 0.79 中移除了旧版 Chrome 调试器 预防: 改用 React Native DevTools(按 ‘j’)

问题 #9:深层导入错误

错误: Module not found: react-native/Libraries/... 来源: React Native 0.80 发布说明 原因: 内部路径已弃用,并强制执行严格 API 预防: 仅从 'react-native' 导入,不要使用深层路径

问题 #10:Redux Store 在 New Architecture 下崩溃

错误: 创建 Redux store 时应用崩溃 来源: Redux Toolkit 迁移指南 原因: 旧版 redux + redux-thunk 与 New Architecture 不兼容 预防: 改用 Redux Toolkit(@reduxjs/toolkit)

问题 #11:i18n-js 在 New Architecture 下不稳定

错误: 翻译未更新,或应用崩溃 来源: 社区报告(GitHub issues) 原因: i18n-js 与 New Architecture 并不完全兼容 预防: 改用 react-i18next

问题 #12:CodePush 在 Android 上崩溃

错误: Android 因查找名为 null 的 bundle 而崩溃 来源: CodePush GitHub 问题 原因: 已知与 New Architecture 不兼容 预防: 在 New Architecture 下避免使用 CodePush,或等待官方支持


迁移指南:0.72-0.75 → 0.82+

步骤 1:先升级到互操作层(0.76-0.81)

原因: 如果使用旧架构,不能直接跳到 0.82,否则会失去互操作层。

# Check current version
npx react-native --version

# Upgrade to 0.81 first (last version with interop layer)
npm install [email protected]
npx expo install --fix
步骤 2:启用 New Architecture(如果尚未启用)
# Android (gradle.properties)
newArchEnabled=true

# iOS
RCT_NEW_ARCH_ENABLED=1 bundle exec pod install

# Rebuild
npm run ios
npm run android
步骤 3:修复不兼容的依赖项

常见的不兼容项:

# Replace Redux with Redux Toolkit
npm uninstall redux redux-thunk
npm install @reduxjs/toolkit react-redux

# Replace i18n-js with react-i18next
npm uninstall i18n-js
npm install react-i18next i18next

# Update React Navigation (if old version)
npm install @react-navigation/native@latest
步骤 4:全面测试
# Run on both platforms
npm run ios
npm run android

# Test all features:
# - Navigation
# - State management (Redux)
# - API calls
# - Deep linking
# - Push notifications
步骤 5:迁移到 React 19(如果升级到 0.78+)
# Run React 19 codemod
npx @codemod/react-19 upgrade

# Manually verify:
# - Remove all propTypes declarations
# - Remove forwardRef wrappers
# - Update to new hooks (useActionState, useOptimistic)
步骤 6:升级到 0.82+
# Only after testing with New Architecture enabled!
npm install [email protected]
npx expo install --fix

# Rebuild
npm run ios
npm run android
步骤 7:将 iOS 迁移到 Swift(新建项目时)

新项目(0.77+)默认使用 Swift。对于现有项目:

# Follow upgrade helper
# https://react-native-community.github.io/upgrade-helper/
# Select: 0.76 → 0.77

# CRITICAL: Add this line to AppDelegate.swift
RCTAppDependencyProvider.sharedInstance()

常见模式

模式 1:使用新 Hooks 进行条件渲染
import { useActionState } from 'react';

function LoginForm() {
  const [state, loginAction, isPending] = useActionState(
    async (prevState, formData) => {
      try {
        const user = await api.login(formData);
        return { success: true, user };
      } catch (error) {
        return { success: false, error: error.message };
      }
    },
    { success: false }
  );

  return (
    <View>
      <form action={loginAction}>
        <TextInput name="email" placeholder="Email" />
        <TextInput name="password" secureTextEntry />
        <Button disabled={isPending}>
          {isPending ? 'Logging in...' : 'Login'}
        </Button>
      </form>
      {!state.success && state.error && (
        <Text style={{ color: 'red' }}>{state.error}</Text>
      )}
    </View>
  );
}

适用场景: 带加载/错误状态的表单提交

模式 2:使用 TypeScript 代替 propTypes
// Define prop types with TypeScript
type ButtonProps = {
  title: string;
  onPress: () => void;
  disabled?: boolean;
  variant?: 'primary' | 'secondary';
};

function Button({ title, onPress, disabled = false, variant = 'primary' }: ButtonProps) {
  return (
    <Pressable
      onPress={onPress}
      disabled={disabled}
      style={[styles.button, styles[variant]]}
    >
      <Text style={styles.text}>{title}</Text>
    </Pressable>
  );
}

适用场景: 始终使用(React 19 中已移除 propTypes)

模式 3:用于视觉效果的新 CSS
// Glowing button with outline and blend mode
function GlowButton({ title, onPress }) {
  return (
    <Pressable
      onPress={onPress}
      style={{
        backgroundColor: '#3b82f6',
        padding: 16,
        borderRadius: 8,
        // Outline doesn't affect layout
        outlineWidth: 2,
        outlineColor: '#60a5fa',
        outlineOffset: 4,
        // Blend with background
        mixBlendMode: 'screen',
        isolation: 'isolate'
      }}
    >
      <Text style={{ color: 'white', fontWeight: 'bold' }}>
        {title}
      </Text>
    </Pressable>
  );
}

适用场景: 实现不影响布局的视觉效果(仅限 New Architecture)


使用捆绑资源

脚本(scripts/)

check-rn-version.sh - 检测 React Native 版本,并提示架构要求

使用示例:

./scripts/check-rn-version.sh
# Output: ✅ React Native 0.82 - New Architecture mandatory
# Output: ⚠️ React Native 0.75 - Upgrade to 0.76+ recommended
参考资料(references/)

react-19-migration.md - React 19 重大变更和迁移步骤详解

new-architecture-errors.md - 启用新架构时的常见构建错误

expo-sdk-52-breaking.md - Expo SDK 52+ 特有的重大变更

Claude 应在以下情况下加载这些资料: 遇到迁移错误、构建失败或 React 19 相关详细问题时

资源(assets/)

new-arch-decision-tree.md - React Native 版本选择决策树

css-features-cheatsheet.md - 新 CSS 属性的完整示例


Expo SDK 52+ 特性

重大变更

Expo Go 中移除 JSC:

// This no longer works in Expo Go (SDK 52+):
{
  "jsEngine": "jsc"  // ❌ Ignored, Hermes only
}

Expo Go 中移除 Google Maps(SDK 53+):

# Must use custom dev client for Google Maps
npx expo install expo-dev-client
npx expo run:android

推送通知警告: Expo Go 会显示推送通知警告——生产环境测试请使用自定义开发客户端。

新功能(SDK 52)

expo/fetch(符合 WinterCG 标准):

import { fetch } from 'expo/fetch';

// Standards-compliant fetch for Workers/Edge runtimes
const response = await fetch('https://api.example.com/data');

React Navigation v7:

npm install @react-navigation/native@^7.0.0

官方文档


软件包版本(已于 2025-11-22 验证)

{
  "dependencies": {
    "react": "^19.1.0",
    "react-native": "^0.82.0",
    "expo": "~52.0.0",
    "@react-navigation/native": "^7.0.0",
    "@reduxjs/toolkit": "^2.0.0",
    "react-i18next": "^15.0.0"
  },
  "devDependencies": {
    "@types/react": "^19.0.0",
    "typescript": "^5.7.0"
  }
}

故障排查

问题:构建失败,并提示“Fabric component descriptor not found”

解决方案: 库与新架构不兼容。查看库文档以确认其是否支持新架构,或使用互操作层(仅适用于 0.76-0.81)。

问题:出现“propTypes is not a function”错误

解决方案: React 19 已移除 propTypes。请改用 TypeScript 进行类型检查。运行 npx @codemod/react-19 upgrade。

问题:Metro 终端中不显示 console.log()

解决方案: 0.77 已移除 Metro 日志转发功能。请使用 React Native DevTools Console(按“j”键),或运行 npx expo start --client-logs(临时解决方法)。

问题:iOS 构建期间出现 Swift AppDelegate 错误

解决方案: 将 RCTAppDependencyProvider.sharedInstance() 添加到 AppDelegate.swift。请参阅 Swift 迁移部分。

问题:Redux store 在启动时崩溃

解决方案: 使用 Redux Toolkit 代替旧版 redux + redux-thunk。请安装 @reduxjs/toolkit。

问题:无法在 0.82+ 中禁用新架构

解决方案: 0.82+ 必须使用新架构。如果需要使用旧架构,请保持在 0.81 或更早版本(不推荐)。


完整设置检查清单

使用此清单检查设置:

  • 已安装 React Native 0.76+ 或 Expo SDK 52+
  • 已启用新架构(0.82+ 中自动启用)
  • 已启用 Hermes 引擎(默认)
  • 已完成 React 19 迁移(不使用 propTypes 和 forwardRef)
  • 已配置 TypeScript 进行类型检查
  • 可使用 React Native DevTools(按“j”键)
  • 不使用深层导入(react-native/Libraries/*)
  • 使用 Redux Toolkit(而非旧版 redux)
  • 使用 react-i18next(而非 i18n-js)
  • iOS 构建成功(新项目使用 Swift 模板)
  • Android 构建成功
  • 开发服务器运行正常,无错误
  • 所有导航和状态管理均正常工作

有疑问?遇到问题?

  1. 查看 references/new-architecture-errors.md 了解构建错误
  2. 查看 references/react-19-migration.md 了解 React 19 相关问题
  3. 查看官方文档:https://reactnative.dev/docs/new-architecture-intro
  4. 确认已启用新架构(0.82+ 中为必需)
  5. 确认所有依赖项均支持新架构

填补知识空白: 此技能涵盖 2024 年 12 月及之后的 React Native 更新,这些内容不在 LLM 的已知范围内。没有此技能,Claude 可能会建议使用已弃用的 API、已移除的功能和过时的模式。

评论

支持 Markdown