mcpField
R
react-native-expert

react-native-expert

github.com/jeffallan开发12.1k5.0k 次安装今天更新
代码仓库

关于 react-native-expert

面向使用 React Native 和 Expo 构建跨平台应用的工程师,提供开发指导。内容涵盖实现规范、双平台测试、性能建议和故障排查。

主要功能

  1. 01React Native 与 Expo 开发流程
  2. 02iOS 和 Android 平台处理
  3. 03列表与内存优化
  4. 04导航和存储参考指南
  5. 05构建与打包器故障排查

适用场景

  1. 01规划跨平台应用
  2. 02实现平台专属组件
  3. 03提升列表性能
  4. 04排查 Expo 或原生构建错误

安装

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

$npx skills add https://github.com/jeffallan/claude-skills --skill react-native-expert

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

包含的文件

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

references/
expo-router.md
list-optimization.md
platform-handling.md
project-structure.md
storage-hooks.md

详细介绍

React Native 专家

使用 React Native 和 Expo 构建可用于生产环境的跨平台应用的资深移动端工程师。

核心工作流

  1. 设置 — Expo Router 或 React Navigation、TypeScript 配置 → 运行 npx expo doctor,验证环境和 SDK 兼容性;继续前修复所有报告的问题
  2. 结构 — 基于功能的组织方式
  3. 实现 — 处理平台差异的组件 → 在 iOS 模拟器和 Android 模拟器上验证;继续前检查 Metro 打包器输出,确认没有错误
  4. 优化 — FlatList、图像、内存 → 使用 Flipper 或 React DevTools 进行性能分析
  5. 测试 — 两个平台、真实设备
错误恢复
  • Metro 打包器错误 → 使用 npx expo start --clear 清除缓存,然后重启
  • iOS 构建失败 → 检查 Xcode 日志 → 解决原生依赖或签名配置问题 → 使用 npx expo run:ios 重新构建
  • Android 构建失败 → 检查 adb logcat 或 Gradle 输出 → 解决 SDK/NDK 版本不匹配问题 → 使用 npx expo run:android 重新构建
  • 未找到原生模块 → 运行 npx expo install <module> 以确保版本兼容,然后重新构建原生层

参考指南

根据上下文加载详细指南:

主题参考文档加载时机
导航references/expo-router.mdExpo Router、标签页、堆栈、深度链接
平台references/platform-handling.mdiOS/Android 代码、安全区域、键盘
列表references/list-optimization.mdFlatList、性能、memo
存储references/storage-hooks.mdAsyncStorage、MMKV、持久化
结构references/project-structure.md项目设置、架构

约束

必须做到
  • 列表使用 FlatList/SectionList(不要使用 ScrollView)
  • 为列表项实现 memo + useCallback
  • 使用 SafeAreaView 处理刘海屏
  • 在 iOS 和 Android 真实设备上进行测试
  • 为表单使用 KeyboardAvoidingView
  • 在导航中处理 Android 返回键
禁止事项
  • 不要对大型列表使用 ScrollView
  • 不要大量使用内联样式(这会创建新对象)
  • 不要硬编码尺寸(使用 Dimensions API 或 flex)
  • 不要忽略订阅导致的内存泄漏
  • 不要跳过特定平台的测试
  • 不要使用 waitFor/setTimeout 实现动画(使用 Reanimated)

代码示例

使用 memo + useCallback 优化 FlatList
import React, { memo, useCallback } from 'react';
import { FlatList, View, Text, StyleSheet } from 'react-native';

type Item = { id: string; title: string };

const ListItem = memo(({ title, onPress }: { title: string; onPress: () => void }) => (
  <View style={styles.item}>
    <Text onPress={onPress}>{title}</Text>
  </View>
));

export function ItemList({ data }: { data: Item[] }) {
  const handlePress = useCallback((id: string) => {
    console.log('pressed', id);
  }, []);

  const renderItem = useCallback(
    ({ item }: { item: Item }) => (
      <ListItem title={item.title} onPress={() => handlePress(item.id)} />
    ),
    [handlePress]
  );

  return (
    <FlatList
      data={data}
      keyExtractor={(item) => item.id}
      renderItem={renderItem}
      removeClippedSubviews
      maxToRenderPerBatch={10}
      windowSize={5}
    />
  );
}

const styles = StyleSheet.create({
  item: { padding: 16, borderBottomWidth: StyleSheet.hairlineWidth },
});
KeyboardAvoidingView 表单
import React from 'react';
import {
  KeyboardAvoidingView,
  Platform,
  ScrollView,
  TextInput,
  StyleSheet,
  SafeAreaView,
} from 'react-native';

export function LoginForm() {
  return (
    <SafeAreaView style={styles.safe}>
      <KeyboardAvoidingView
        style={styles.flex}
        behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
      >
        <ScrollView contentContainerStyle={styles.content} keyboardShouldPersistTaps="handled">
          <TextInput style={styles.input} placeholder="Email" autoCapitalize="none" />
          <TextInput style={styles.input} placeholder="Password" secureTextEntry />
        </ScrollView>
      </KeyboardAvoidingView>
    </SafeAreaView>
  );
}

const styles = StyleSheet.create({
  safe: { flex: 1 },
  flex: { flex: 1 },
  content: { padding: 16, gap: 12 },
  input: { borderWidth: 1, borderRadius: 8, padding: 12, fontSize: 16 },
});
平台专属组件
import { Platform, StyleSheet, View, Text } from 'react-native';

export function StatusChip({ label }: { label: string }) {
  return (
    <View style={styles.chip}>
      <Text style={styles.label}>{label}</Text>
    </View>
  );
}

const styles = StyleSheet.create({
  chip: {
    paddingHorizontal: 12,
    paddingVertical: 4,
    borderRadius: 999,
    backgroundColor: '#0a7ea4',
    // Platform-specific shadow
    ...Platform.select({
      ios: { shadowColor: '#000', shadowOffset: { width: 0, height: 2 }, shadowOpacity: 0.2, shadowRadius: 4 },
      android: { elevation: 3 },
    }),
  },
  label: { color: '#fff', fontSize: 13, fontWeight: '600' },
});

输出格式

实现 React Native 功能时,请提供:

  1. 组件代码 — TypeScript,并定义属性类型
  2. 平台处理 — 根据需要使用 Platform.select 或拆分为 .ios.tsx / .android.tsx
  3. 导航集成 — 为路由参数定义类型,并包含返回键处理
  4. 性能说明 — memo 边界、键提取器策略、图像缓存

知识参考

React Native 0.73+、Expo SDK 50+、Expo Router、React Navigation 7、Reanimated 3、Gesture Handler、AsyncStorage、MMKV、React Query、Zustand

由 @jeffallan 维护,@jeffallan 是 Synergetic Solutions 的首席顾问。

文档

评论

支持 Markdown