ReactNativeExpo移动开发技能Skill react-native-expo

此技能专注于使用Expo SDK 52+和React Native 0.76+进行移动应用开发,覆盖新架构强制启用、React 19变化、CSS新特性、Swift iOS模板迁移等关键内容,帮助开发者构建、迁移和解决常见问题。关键词:React Native, Expo, 移动开发, 新架构, React 19, 迁移指南, 移动应用开发, 前端技术。

移动开发 0 次安装 0 次浏览 更新于 3/13/2026

名称: react-native-expo 描述: | 使用Expo SDK 52构建React Native 0.76+应用。覆盖强制新架构(0.82+)、React 19变化(propTypes/forwardRef移除)、新CSS属性(display: contents, mixBlendMode, outline)、Swift iOS模板和DevTools迁移。

使用场景: 构建Expo应用、迁移到新架构或解决“Fabric组件未找到”、“propTypes不是函数”、“TurboModule未注册”或Swift AppDelegate错误。

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

状态: 生产就绪 最后更新: 2025-11-22 依赖: Node.js 18+, Expo CLI 最新版本: react-native@0.82, expo@~52.0.0, react@19.1


快速开始 (15分钟)

1. 创建新Expo项目 (RN 0.76+)

# 使用React Native 0.76+创建新Expo应用
npx create-expo-app@latest my-app

cd my-app

# 安装最新依赖
npx expo install react-native@latest expo@latest

为何重要:

  • Expo SDK 52+默认使用启用了新架构的React Native 0.76+
  • 新架构在React Native 0.82+中是强制性的(无法禁用)
  • Hermes是唯一支持的JavaScript引擎(JSC已从Expo Go移除)

2. 验证新架构已启用

# 检查新架构是否启用(默认应为true)
npx expo config --type introspect | grep newArchEnabled

关键:

  • React Native 0.82+ 要求新架构 - 旧架构完全移除
  • 如果从0.75或更早版本迁移,首先升级到0.76-0.81以使用互操作层
  • 切勿尝试在0.82+中禁用新架构(构建将失败)

3. 启动开发服务器

# 启动Expo开发服务器
npx expo start

# 按'i'启动iOS模拟器
# 按'a'启动Android模拟器
# 按'j'打开React Native DevTools(非Chrome调试器!)

关键:

  • 旧Chrome调试器在0.79中移除 - 改用React Native DevTools
  • Metro终端不再流式传输console.log() - 使用DevTools控制台
  • 键盘快捷键’a’/'i’在CLI中有效,不在Metro终端中

关键破坏性变化 (2024年12月+)

🔴 新架构强制启用 (0.82+)

变化:

  • 0.76-0.81: 新架构默认启用,旧架构冻结(无新功能)
  • 0.82+: 旧架构完全移除自代码库

影响:

# 这在0.82+中将失败:
# gradle.properties (Android)
newArchEnabled=false  # ❌ 被忽略,构建失败

# iOS
RCT_NEW_ARCH_ENABLED=0  # ❌ 被忽略,构建失败

迁移路径:

  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 = {  // ❌ 在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>;
}

迁移:

# 使用React 19 codemod移除propTypes
npx @codemod/react-19 upgrade

🔴 forwardRef弃用 (React 19)

变化: forwardRef不再需要 - 将ref作为常规prop传递。

之前 (旧代码):

import { forwardRef } from 'react';

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

之后 (React 19):

function MyInput({ ref, ...props }) {  // ✅ ref是常规prop
  return <TextInput ref={ref} {...props} />;
}

🔴 Swift iOS模板默认 (0.77+)

变化: 新项目使用Swift AppDelegate.swift而非Objective-C AppDelegate.mm

旧结构:

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

新结构:

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

@main
class AppDelegate: UIResponder, UIApplicationDelegate {
  func application(_ application: UIApplication, ...) -> Bool {
    // 应用初始化
    return true
  }
}

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

// 迁移期间添加到AppDelegate.swift
import React
import ReactCoreModules

RCTAppDependencyProvider.sharedInstance()  // ⚠️ 关键:必须添加此!

来源: React Native 0.77发布说明

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

变化: Metro终端不再流式传输console.log()输出。

之前 (0.76):

# console.log()出现在Metro终端
$ npx expo start
> LOG  Hello from app!  # ✅ 出现在这里

之后 (0.77+):

# console.log()不出现于Metro终端
$ npx expo start
# (无日志显示)  # ❌ 移除

# 临时解决方案(将移除):
$ npx expo start --client-logs  # 显示日志,已弃用

解决方案: 改用React Native DevTools控制台(在CLI中按’j’)。

来源: React Native 0.77发布说明

🔴 Chrome调试器移除 (0.79+)

变化: 旧Chrome调试器(chrome://inspect)移除。改用React Native DevTools。

旧方法 (已移除):

# ❌ 此不再工作:
# 打开Dev菜单 → “调试” → Chrome DevTools打开

新方法 (0.76+):

# 在CLI中按'j'或Dev菜单 → “打开React Native DevTools”
# ✅ 使用Chrome DevTools协议 (CDP)
# ✅ 可靠断点、监视值、堆栈检查
# ✅ JS控制台(替换Metro日志)

限制:

  • 第三方扩展尚未支持(Redux DevTools等)
  • 网络检查器将在0.83中添加(2025年底)

来源: React Native 0.79发布说明

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

变化: JavaScriptCore (JSC)移出React Native核心,Hermes是默认。

之前 (0.78):

  • Hermes和JSC捆绑
  • JSC在Expo Go中可用

之后 (0.79+):

// 如果仍需要JSC(罕见):
{
  "dependencies": {
    "@react-native-community/javascriptcore": "^1.0.0"
  }
}

Expo Go:

  • JSC完全从Expo Go移除(SDK 52+)
  • 仅Hermes

注意: JSC最终将从React Native完全移除。

🔴 深层导入弃用 (0.80+)

变化: 从内部路径导入将破坏。

之前 (旧代码):

// ❌ 深层导入弃用
import Button from 'react-native/Libraries/Components/Button';
import Platform from 'react-native/Libraries/Utilities/Platform';

之后:

// ✅ 仅从'react-native'导入
import { Button, Platform } from 'react-native';

来源: React Native 0.80发布说明


新功能 (2024年12月后)

CSS属性 (0.77+ 仅新架构)

React Native现支持许多先前仅web可用的CSS属性:

1. display: contents

使元素“不可见”但保持其子元素在布局中:

<View style={{ display: 'contents' }}>
  {/* 此View消失,但Text仍渲染 */}
  <Text>我仍在这里!</Text>
</View>

用例: 不应影响布局的包装组件。

2. boxSizing

控制宽度/高度计算方式:

// 默认:填充/边框在框内
<View style={{
  boxSizing: 'border-box',  // 默认
  width: 100,
  padding: 10,
  borderWidth: 2
  // 总宽度:100(填充/边框在内)
}} />

// 内容框:填充/边框在外
<View style={{
  boxSizing: 'content-box',
  width: 100,
  padding: 10,
  borderWidth: 2
  // 总宽度:124(100 + 20填充 + 4边框)
}} />

3. mixBlendMode + isolation

类似Photoshop的层混合:

<View style={{ backgroundColor: 'red' }}>
  <View style={{
    mixBlendMode: 'multiply',  // 16种模式可用
    backgroundColor: 'blue'
    // 结果:紫色(红 × 蓝)
  }} />
</View>

// 防止意外混合:
<View style={{ isolation: 'isolate' }}>
  {/* 混合限制在此视图内 */}
</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,           // 元素与轮廓之间的空间
  outlineSpread: 2            // 扩展轮廓超出偏移
}} />

关键区别: 轮廓不改变元素大小或触发布局重新计算。

来源: React Native 0.77发布说明

Android XML Drawables (0.78+)

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

// 构建时加载XML drawable
import MyIcon from './assets/my_icon.xml';

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

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

优势:

  • 可缩放矢量图形(分辨率无关)
  • 比PNG更小的APK大小
  • 离线程解码(更好性能)

限制:

  • 仅构建时资源(无网络加载)
  • 仅Android(iOS仍使用SF符号或PNG)

来源: React Native 0.78发布说明

React 19 新Hooks

1. useActionState (替换表单模式)

import { useActionState } from 'react';

function MyForm() {
  const [state, submitAction, isPending] = useActionState(
    async (prevState, formData) => {
      // 异步表单提交
      const result = await api.submit(formData);
      return result;
    },
    { message: '' }  // 初始状态
  );

  return (
    <form action={submitAction}>
      <TextInput name="email" />
      <Button disabled={isPending}>
        {isPending ? '提交中...' : '提交'}
      </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);  // 立即更新UI
    await api.like(postId);  // 然后更新服务器
  }

  return (
    <Button onPress={handleLike}>
      ❤️ {optimisticLikes}
    </Button>
  );
}

3. use (渲染期间读取promise/context)

import { use } from 'react';

function UserProfile({ userPromise }) {
  // 渲染期间直接读取promise(如果pending则暂停)
  const user = use(userPromise);

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

来源: React 19升级指南

React Native DevTools (0.76+)

访问:

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

功能:

  • ✅ 可靠断点(不同于旧Chrome调试器)
  • ✅ 监视值、调用堆栈检查
  • ✅ JS控制台(替换Metro日志)
  • ✅ 基于Chrome DevTools协议 (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 来源: 新架构迁移指南 为何发生: 原生模块需要新架构支持(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发布说明 为何发生: Metro日志转发在0.77移除 预防: 使用React Native DevTools控制台(按’j’),或--client-logs标志(临时)

问题 #8: Chrome调试器不工作

错误: Chrome DevTools不连接 来源: React Native 0.79发布说明 为何发生: 旧Chrome调试器在0.79移除 预防: 改用React Native DevTools(按’j’)

问题 #9: 深层导入错误

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

问题 #10: Redux商店与新架构崩溃

错误: 应用在Redux商店创建时崩溃 来源: Redux Toolkit迁移指南 为何发生: 旧redux + redux-thunk与新架构不兼容 预防: 改用Redux Toolkit(@reduxjs/toolkit

问题 #11: i18n-js与新架构不可靠

错误: 翻译不更新,或应用崩溃 来源: 社区报告(GitHub issues) 为何发生: i18n-js未完全兼容新架构 预防: 改用react-i18next

问题 #12: CodePush在Android崩溃

错误: Android崩溃寻找名为null的bundle 来源: CodePush GitHub Issues 为何发生: 已知与新架构不兼容 预防: 避免在新架构中使用CodePush,或等待官方支持


迁移指南: 0.72-0.75 → 0.82+

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

为何: 如果使用旧架构,无法直接跳到0.82 - 将失去互操作层。

# 检查当前版本
npx react-native --version

# 首先升级到0.81(最后有互操作层的版本)
npm install react-native@0.81
npx expo install --fix

步骤 2: 启用新架构(如果尚未)

# Android (gradle.properties)
newArchEnabled=true

# iOS
RCT_NEW_ARCH_ENABLED=1 bundle exec pod install

# 重新构建
npm run ios
npm run android

步骤 3: 修复不兼容依赖

常见不兼容性:

# 用Redux Toolkit替换Redux
npm uninstall redux redux-thunk
npm install @reduxjs/toolkit react-redux

# 用react-i18next替换i18n-js
npm uninstall i18n-js
npm install react-i18next i18next

# 更新React Navigation(如果旧版本)
npm install @react-navigation/native@latest

步骤 4: 全面测试

# 在两个平台运行
npm run ios
npm run android

# 测试所有功能:
# - 导航
# - 状态管理(Redux)
# - API调用
# - 深度链接
# - 推送通知

步骤 5: 迁移到React 19(如果升级到0.78+)

# 运行React 19 codemod
npx @codemod/react-19 upgrade

# 手动验证:
# - 移除所有propTypes声明
# - 移除forwardRef包装
# - 更新到新hooks(useActionState、useOptimistic)

步骤 6: 升级到0.82+

# 仅在新架构启用测试后!
npm install react-native@0.82
npx expo install --fix

# 重新构建
npm run ios
npm run android

步骤 7: 迁移iOS到Swift(如果新项目)

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

# 跟随升级助手
# https://react-native-community.github.io/upgrade-helper/
# 选择:0.76 → 0.77

# 关键:添加此行到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="邮箱" />
        <TextInput name="password" secureTextEntry />
        <Button disabled={isPending}>
          {isPending ? '登录中...' : '登录'}
        </Button>
      </form>
      {!state.success && state.error && (
        <Text style={{ color: 'red' }}>{state.error}</Text>
      )}
    </View>
  );
}

使用时机: 表单提交与加载/错误状态

模式 2: 使用TypeScript而非propTypes

// 用TypeScript定义prop类型
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>
  );
}

使用时机: 总是(propTypes在React 19移除)

模式 3: 用于视觉效果的新CSS

// 带轮廓和混合模式的发光按钮
function GlowButton({ title, onPress }) {
  return (
    <Pressable
      onPress={onPress}
      style={{
        backgroundColor: '#3b82f6',
        padding: 16,
        borderRadius: 8,
        // 轮廓不影响布局
        outlineWidth: 2,
        outlineColor: '#60a5fa',
        outlineOffset: 4,
        // 与背景混合
        mixBlendMode: 'screen',
        isolation: 'isolate'
      }}
    >
      <Text style={{ color: 'white', fontWeight: 'bold' }}>
        {title}
      </Text>
    </Pressable>
  );
}

使用时机: 不影响布局的视觉效果(仅新架构)


使用捆绑资源

脚本 (scripts/)

check-rn-version.sh - 检测React Native版本并警告架构要求

示例用法:

./scripts/check-rn-version.sh
# 输出:✅ React Native 0.82 - 新架构强制启用
# 输出:⚠️ React Native 0.75 - 推荐升级到0.76+

参考 (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+ 详情

破坏性变化

JSC从Expo Go移除:

// 这在Expo Go(SDK 52+)中不再工作:
{
  "jsEngine": "jsc"  // ❌ 忽略,仅Hermes
}

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

# 必须使用自定义dev client进行Google Maps
npx expo install expo-dev-client
npx expo run:android

推送通知警告: Expo Go显示推送通知警告 - 使用自定义dev client进行生产测试。

新功能 (SDK 52)

expo/fetch (WinterCG兼容):

import { fetch } from 'expo/fetch';

// 用于Workers/Edge运行时的标准兼容fetch
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组件描述符未找到”

解决方案: 库不兼容新架构。检查库文档以获取新架构支持,或使用互操作层(仅0.76-0.81)。

问题: “propTypes不是函数”错误

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

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

解决方案: Metro日志转发在0.77移除。使用React Native DevTools控制台(按’j’)或npx expo start --client-logs(临时解决方案)。

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

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

问题: Redux商店在启动时崩溃

解决方案: 用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更新,LLMs将不会知道。无此技能,Claude会建议弃用API、移除功能和过时模式。