expo-quick-actions Hooks实战:useQuickAction与useQuickActionCallback如何选?一篇讲透
【免费下载链接】expo-quick-actionsAdd home screen quick actions / shortcuts and custom icons to your Expo app项目地址: https://gitcode.com/gh_mirrors/ex/expo-quick-actions
expo-quick-actions 是一个为 Expo 应用添加主屏幕快捷操作(Quick Actions)和动态应用图标的开源库。本文聚焦它最常被问到的问题:两个 Hook ——useQuickAction和useQuickActionCallback—— 到底有什么区别、怎么选。读完这篇,你就能在项目中一次性用对它们。
什么是 Quick Actions,为什么需要 Hooks?
长按手机桌面图标(iOS 长按、Android 长按)会弹出应用自定义的快捷入口,比如"新建聊天""搜索""拍照"。expo-quick-actions 用一套 API 帮你:
- 设置快捷项:
setItems定义快捷操作的标题、图标、参数; - 监听启动事件:用户点了哪个快捷项、带着什么参数启动应用,通过 Hooks 拿到;
- 动态换图标:
expo-quick-actions/icon子模块可运行时切换应用图标。
核心 API 定义在 src/index.ts,它暴露了initial(冷启动时命中的快捷项)、maxCount(最大快捷项数量)、setItems、isSupported和addListener。两个 Hooks 就是对initial + addListener这套组合的封装,定义在 src/hooks.ts。
两个 Hook 一图看懂:核心差异
| 对比项 | useQuickAction | useQuickActionCallback |
|---|---|---|
| 返回值 | 当前快捷项对象(Action \| null) | 无,只注册回调 |
| 会触发组件重渲染吗? | ✅ 会,每次快捷项变化都 setState | ❌ 不会,事件在回调里处理 |
| 典型场景 | 用快捷项数据更新界面 | 导航跳转、埋点统计、全局状态 |
| 冷启动时命中快捷项 | 通过initial自动读入 | 立即以initial调用一次回调 |
一句话总结:要改 UI 用useQuickAction,只做事不改 UI 用useQuickActionCallback。
useQuickActionCallback:不重渲染的事件处理器
看 src/hooks.ts 的注释写得很直白:它"防止组件因操作变化而整体重渲染"。内部用useEffect订阅原生事件,组件卸载时自动取消订阅,并处理了冷启动的initial事件,你无需重复处理。
适合放在布局组件、全局容器、Provider里,做导航、埋点这类全局行为:
import { useQuickActionCallback } from "expo-quick-actions/hooks"; function Layout() { useQuickActionCallback((action) => { // 全局行为:跳转或打点,不影响任何界面渲染 console.log("快捷项被触发:", action); }); // ... }为什么"不重渲染"很重要?
如果把监听放进一个页面组件并让它重渲染,每次用户从快捷项进入都会导致整棵组件树刷新。回调式监听把副作用隔离在事件处理里,是更轻量的做法。
useQuickAction:让界面直接响应快捷项
当快捷项的参数本身要驱动 UI(比如根据params高亮某个 Tab、展示对应内容),就用它。它会返回最近一次启动应用的快捷项,没有则为null:
import { useQuickAction } from "expo-quick-actions/hooks"; function Home() { const action = useQuickAction(); // action 变化时组件重渲染,据此更新界面 return action ? <Detail action={action} /> : <Welcome />; }官方示例 example/App.tsx 就是这么写的:const action = useQuickAction(),然后把 action 的 JSON 直接渲染到页面上,非常直观的演示。
实战决策:3 个信号快速选型
遇到需求时按顺序问自己:
- 拿到快捷项后要不要改变界面?要 →
useQuickAction; - 只是导航 / 埋点 / 发请求?→
useQuickActionCallback; - 项目在用 Expo Router?优先用 src/router.ts 提供的
useQuickActionRouting,它内部就是基于回调实现的:只要快捷项带params.href,就会自动router.navigate到对应路由,还能传自定义 callback 拦截处理。
// app/(root)/_layout.tsx import { useQuickActionRouting } from "expo-quick-actions/router"; export default function Layout() { useQuickActionRouting(); // 快捷项 params.href 直接变成路由跳转 return <Slot />; }⚠️ 官方提醒:
useQuickActionRouting应放在子布局(app/(root)/_layout.tsx)而不是根布局,因为它会触发导航。
别忘了:先设置快捷项,再监听
两个 Hook 只是"接收端"。发送端是setItems,在应用启动时配置一次即可:
QuickActions.setItems([ { id: "compose", title: "新建", icon: "compose", params: { href: "/compose" } }, { id: "search", title: "搜索", icon: "search", params: { href: "/search" } }, ]);配合 Config Plugin(plugin/src/index.ts)还能在app.json里声明静态的 Android 自适应图标、iOS 图标与 iOS 静态快捷项,示例项目 example/app.json 给了完整配置参考。
常见问题(FAQ)
Q1:冷启动时用户从快捷项进入,回调会触发吗?会。两个 Hook 都会检查QuickActions.initial,冷启动命中的快捷项会被"补发"一次,不会丢事件。
Q2:能同时使用两个 Hook 吗?可以,但没必要在同一个组件里混用。推荐分工:全局布局里挂useQuickActionCallback做导航,具体页面里用useQuickAction做界面响应。
Q3:Web 端会报错吗?不会。src/index.web.ts 提供了空实现,isSupported返回false,事件监听为 no-op,可安全跨端引用。
总结
- 改 UI →
useQuickAction;只做副作用 →useQuickActionCallback,这是唯一的选型主线; - 用 Expo Router 的项目直接用
useQuickActionRouting,一行代码打通"快捷项 → 路由"; - 别忘了先
setItems,再谈监听。
掌握这套组合,你的 Expo 应用就能拥有原生的主屏幕快捷入口和动态图标体验。
【免费下载链接】expo-quick-actionsAdd home screen quick actions / shortcuts and custom icons to your Expo app项目地址: https://gitcode.com/gh_mirrors/ex/expo-quick-actions
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考