mcpField
C
capacitor-react

capacitor-react

github.com/capawesome-team开发52992 次安装1 周前更新
代码仓库

关于 capacitor-react

面向使用 React 构建 Capacitor 应用的开发者,提供项目分析、原生功能接入及 React 模式指导。内容涵盖平台判断、自定义 Hook、状态管理和导航等实践。

主要功能

  1. 01自动识别项目配置
  2. 02集成 Capacitor 插件
  3. 03封装原生功能自定义 Hook
  4. 04处理深度链接与应用生命周期
  5. 05按平台调整渲染与调用

适用场景

  1. 01为现有 React 项目接入 Capacitor
  2. 02在组件中安全使用原生插件
  3. 03处理应用恢复和 Android 返回键

安装

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

$npx skills add https://github.com/capawesome-team/skills --skill capacitor-react

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

附带文件references/custom-hooks.mdreferences/plugin-usage-patterns.md

详细介绍

Capacitor React

使用 React 开发 Capacitor 应用——项目结构、钩子、状态管理,以及访问原生设备功能的 React 专属模式。

前置条件

  1. 使用 React 的 Capacitor 6、7 或 8 应用。
  2. 已安装 Node.js 和 npm。
  3. React 18 或更高版本。
  4. 对于 iOS:已安装 Xcode。
  5. 对于 Android:已安装 Android Studio。

Agent 行为

  • 先自动检测,再提问。 检查项目中的 package.json 依赖项(react、react-dom、@capacitor/core)、平台目录(android/、ios/)、构建工具(vite.config.ts、next.config.js、webpack.config.js)以及 TypeScript 的使用情况。只有在无法检测到某项信息时,才询问用户。
  • 逐步引导。 一次引导用户完成一个步骤。不要同时提出多个无关问题。
  • 适配项目。 检测现有代码风格(函数组件还是类组件、TypeScript 还是 JavaScript、CSS 模块还是 styled-components),并生成风格一致的代码。

流程

步骤 1:分析项目

通过读取项目文件,自动检测以下内容:

  1. 框架类型:检查 package.json 依赖项和配置文件(vite.config.ts、next.config.js、remix.config.js),判断这是普通 React 应用(Vite/CRA)、Next.js 还是 Remix。
  2. Capacitor 版本:从 package.json 中读取 @capacitor/core 版本。
  3. React 版本:从 package.json 中读取 react 版本。
  4. TypeScript:检查是否存在 tsconfig.json,以及是否使用 .tsx 文件。
  5. 平台:检查哪些目录存在(android/、ios/)。
  6. Capacitor 配置格式:检查项目使用的是 capacitor.config.ts 还是 capacitor.config.json。
  7. 状态管理:检查 package.json 中是否包含 redux、@reduxjs/toolkit、zustand、jotai、@tanstack/react-query 或类似依赖。
  8. 路由器:检查 package.json 中是否包含 react-router-dom、@tanstack/react-router 或类似依赖。
步骤 2:项目结构

标准的 Capacitor React 项目采用以下结构:

project-root/
├── android/                  # Android native project (generated by Capacitor)
├── ios/                      # iOS native project (generated by Capacitor)
├── public/
├── src/
│   ├── components/           # Reusable UI components
│   ├── hooks/                # Custom React hooks (including native feature hooks)
│   ├── pages/                # Page/route components
│   ├── services/             # Service modules for Capacitor plugin calls
│   ├── App.tsx               # Root component
│   └── main.tsx              # Entry point
├── capacitor.config.ts       # Capacitor configuration
├── package.json
├── tsconfig.json
└── vite.config.ts            # Or other bundler config

如果项目不符合此结构,请根据项目的实际目录布局调整所有指导。除非用户明确要求,否则不要重构项目。

步骤 3:在 React 中使用 Capacitor 插件

阅读 references/plugin-usage-patterns.md,了解在 React 组件和钩子中使用 Capacitor 插件的详细模式。

主要原则:

  1. 直接导入插件——Capacitor 插件以 ES 模块形式导入。
  2. 在事件处理程序或 effect 中调用插件方法——不要在模块顶层调用。
  3. 使用 useEffect 注册监听器——在 useEffect 中注册并清理 Capacitor 事件监听器。
  4. 调用前检查平台——使用 Capacitor.isNativePlatform() 或 Capacitor.getPlatform() 为特定平台的调用添加保护。
步骤 4:原生功能的自定义钩子

阅读 references/custom-hooks.md,了解封装 Capacitor 插件的可复用自定义钩子模式。

自定义钩子封装对原生功能的访问,并提供符合 React 习惯的 API。当用户需要从多个组件访问某项原生功能时,请在 src/hooks/(或项目存放钩子的位置)中创建自定义钩子。

步骤 5:使用原生数据进行状态管理

如果项目使用状态管理库,请按以下方式集成原生数据:

  1. React Query / TanStack Query:使用调用 Capacitor 插件的查询函数。这非常适合从原生 API 获取的数据(例如设备信息、联系人、文件系统读取结果)。
  2. Redux / Zustand / Jotai:从 Capacitor 插件回调中分发操作或更新原子状态。将原生 API 调用放在操作创建器或服务模块中,不要放在 reducer 或 store 中。
  3. 不使用状态库:使用 React context,或结合 useState/useReducer 的自定义钩子,在组件间共享原生数据。

除非用户的需求确有必要,否则不要建议添加状态管理库。

步骤 6:导航和深层链接

如果项目使用 react-router-dom 或其他路由器:

  1. 深层链接:在根组件或专用 Hook 的 useEffect 中,为 @capacitor/app 插件的 appUrlOpen 事件注册监听器。使用路由器的 useNavigate() Hook 以编程方式导航。
import { useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
import { App, URLOpenListenerEvent } from '@capacitor/app';

const useDeepLinks = () => {
  const navigate = useNavigate();

  useEffect(() => {
    const listener = App.addListener('appUrlOpen', (event: URLOpenListenerEvent) => {
      const path = new URL(event.url).pathname;
      navigate(path);
    });

    return () => {
      listener.then(handle => handle.remove());
    };
  }, [navigate]);
};
  1. 返回按钮处理(Android):为 @capacitor/app 插件的 backButton 事件注册监听器,以处理 Android 硬件返回按钮的按下操作。
import { useEffect } from 'react';
import { useNavigate, useLocation } from 'react-router-dom';
import { App } from '@capacitor/app';

const useBackButton = () => {
  const navigate = useNavigate();
  const location = useLocation();

  useEffect(() => {
    const listener = App.addListener('backButton', ({ canGoBack }) => {
      if (canGoBack) {
        navigate(-1);
      } else {
        App.exitApp();
      }
    });

    return () => {
      listener.then(handle => handle.remove());
    };
  }, [navigate, location]);
};
步骤 7:平台特定渲染

使用 Capacitor.getPlatform() 或 Capacitor.isNativePlatform() 有条件地渲染组件或应用平台特定行为:

import { Capacitor } from '@capacitor/core';

const MyComponent: React.FC = () => {
  const platform = Capacitor.getPlatform(); // 'ios' | 'android' | 'web'
  const isNative = Capacitor.isNativePlatform();

  return (
    <div>
      {platform === 'ios' && <IOSSpecificComponent />}
      {platform === 'android' && <AndroidSpecificComponent />}
      {!isNative && <WebFallbackComponent />}
    </div>
  );
};

如需复用平台检查逻辑,请创建工具函数或 Hook:

import { Capacitor } from '@capacitor/core';

export const usePlatform = () => {
  return {
    platform: Capacitor.getPlatform(),
    isNative: Capacitor.isNativePlatform(),
    isIOS: Capacitor.getPlatform() === 'ios',
    isAndroid: Capacitor.getPlatform() === 'android',
    isWeb: Capacitor.getPlatform() === 'web',
  };
};
步骤 8:生命周期和应用状态

使用 @capacitor/app 插件在 React 中响应应用生命周期事件:

import { useEffect } from 'react';
import { App } from '@capacitor/app';

const useAppState = (onResume?: () => void, onPause?: () => void) => {
  useEffect(() => {
    const resumeListener = App.addListener('resume', () => {
      onResume?.();
    });

    const pauseListener = App.addListener('pause', () => {
      onPause?.();
    });

    return () => {
      resumeListener.then(handle => handle.remove());
      pauseListener.then(handle => handle.remove());
    };
  }, [onResume, onPause]);
};

使用此功能可在应用返回前台时刷新数据、暂停媒体,或在应用切换到后台时保存状态。

步骤 9:构建和运行

完成更改后:

npm run build
npx cap sync
npx cap run android
npx cap run ios

如需在开发期间启用实时重载:

npx cap run android --livereload --external
npx cap run ios --livereload --external

--external 标志可让设备/模拟器访问开发服务器。--livereload 标志可在源文件更改时启用自动重载。

错误处理

  • 运行时未找到插件:确保安装插件后运行了 npx cap sync。确认插件已列在 package.json 依赖项中。
  • Capacitor is not defined:必须安装 @capacitor/core 包。运行 npm install @capacitor/core。
  • 原生方法在 Web 上失败:使用 Capacitor.isNativePlatform() 为仅限原生平台的调用添加保护。许多插件提供 Web 实现,但有些插件(例如带有原生 UI 的 @capacitor/camera)仅适用于 iOS/Android。
  • 事件监听器内存泄漏:始终从 useEffect 返回一个清理函数,并在其中对监听器句柄调用 remove()。否则,重新渲染时会产生重复的监听器。
  • 事件监听器中的闭包过期:如果 Capacitor 事件监听器引用了随时间变化的 React 状态,请使用 useRef 保存最新值,或将状态变量添加到 useEffect 依赖数组中并重新注册监听器。
  • 实时重载无法连接:确保设备和开发机器处于同一网络。检查是否在 npx cap run 中使用了 --external 标志。确认防火墙未阻止开发服务器端口。
  • Web 构建成功,但原生构建失败:检查是否有未使用 Capacitor 替代方案的仅限浏览器 API(window.localStorage、navigator.geolocation)。请改用 Capacitor 插件(@capacitor/preferences、@capacitor/geolocation)。
  • React 严格模式重复挂载:在开发环境中,React 18 严格模式会挂载组件两次。这可能导致 Capacitor 事件监听器重复。确保清理函数能正确移除监听器;重复挂载行为可用于验证清理是否正常工作。

相关技能

  • ionic-react — 为使用 @ionic/react 的应用提供 Ionic Framework 特定的 React 模式(IonReactRouter、生命周期 Hook、覆盖层 Hook)。
  • capacitor-angular — Capacitor 应用开发的 Angular 特定模式和最佳实践。
  • capacitor-app-upgrades — 将 Capacitor 应用升级到较新的主版本。
  • capacitor-plugins — 安装、配置和使用来自官方及社区来源的 Capacitor 插件。
  • capacitor-push-notifications — 在 Capacitor 应用中使用 Firebase Cloud Messaging 设置推送通知。

评论

支持 Markdown