news 2026/8/25 9:35:56

Pressto交互状态解析:isPressed、isToggled、isSelected如何让按钮拥有记忆

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Pressto交互状态解析:isPressed、isToggled、isSelected如何让按钮拥有记忆

Pressto交互状态解析:isPressed、isToggled、isSelected如何让按钮拥有记忆

【免费下载链接】presstoYour React Native app deserves better tap interactions.项目地址: https://gitcode.com/gh_mirrors/pre/pressto

Pressto 是一个运行在主线程上的 React Native 按钮动画库,通过内置的 isPressed、isToggled、isSelected 三种交互状态,让按钮既能给出"按下去的瞬间反馈",又能"记住"开关与选中的持久状态,全程无需手写 useState。本文带你逐个解析这三个状态的工作机制,并用 3 步写出带记忆的按钮。

为什么按钮需要"记忆"?

React Native 按钮的一个常见痛点:手指按下时,希望按钮有"被按下"的缩放或变暗反馈;手指抬起后,又希望部分按钮记住状态——比如"已收藏"还是"未收藏"、Tab 当前选中哪一个。

Pressto 的巧妙之处在于:它把三种状态直接封装进每个 pressable 组件,你在动画函数里直接读取即可,状态切换全部由库自动维护。

状态生命周期触发时机是否持久典型场景
isPressed瞬时手指按下 → 抬起按压缩放、变暗反馈
isToggled持久每次点击自动翻转开关、收藏、静音
isSelected持久组内最后被点中Tab 切换、单选列表

isPressed:手指按下的那一刻

isPressed 最直观:手指按下瞬间为 true,抬起即恢复 false,并驱动 0→1 的动画进度值 progress,内置的缩放、透明度假动画就是靠它。

在源码 src/pressables/base.tsx 中,active共享值在按下(onPressIn)时被设为 true,而onEndedonCancelledonFailed事件统一映射到 onPressOut——这意味着"手指滑出按钮区域"或"长按失败"都会视为抬起,按钮不会卡在按压状态。

另外在 Web 平台启用activateOnHover后,鼠标悬停也会激活按压状态,让桌面端同样有动效反馈。

isToggled:每次点击翻转的开关记忆

isToggled 是"记忆"的核心:每点一次就在 true / false 之间自动翻转,并且跨点击保留。初始值可由initialToggled属性设置(默认 false),适合"默认已静音"之类的场景。

翻转逻辑就在 src/pressables/base.tsx 的按下处理器里:每次成功点击执行isToggled.set(!isToggled.get()),你完全不用手动管理状态。这个行为有完善的单元测试守护,见 src/tests/handlers.test.tsx——连续点击三次,状态依次为 true、false、true。

isSelected:组内"最后选中"的标记

isSelected 专为按钮组设计:组内任意一个按钮被点击后,只有它是 true,之前选中的自动变 false。你不需要维护 selected 索引或数组,库内部用共享的"最后被触碰"标识做了这件事。

其派生逻辑同样在 src/pressables/base.tsx 中:将 src/provider/context.ts 里 PressablesGroupContext 提供的lastTouchedPressable共享值与自身唯一 ID 比对,相等即处于选中态。

三步写出带记忆的按钮

  1. 创建自定义 pressable:用createAnimatedPressable包装一个动画函数(定义于 src/pressables/hoc.tsx)。
  2. 读取三个状态:从 options 中解构 isPressed、isToggled、isSelected。
  3. 交给 withAnimation:options 自带预配置的动画函数,颜色和数值变化都会自动平滑过渡。

一个最小的切换按钮示例:

const ToggleButton = createAnimatedPressable((progress, options) => { 'worklet'; const { isPressed, isToggled, isSelected, withAnimation } = options; return { backgroundColor: withAnimation(isToggled ? '#4CAF50' : '#2196F3'), opacity: isPressed ? 0.8 : 1, borderWidth: isSelected ? 3 : 0, }; });

⚠️ 注意:动画函数首行必须写'worklet';指令,否则动画无法运行在主线程。

除了在动画函数里用,事件回调也能读取这三个状态:onPress/onPressIn/onPressOut都会收到{ isPressed, isToggled, isSelected, metadata }快照(类型定义见 src/provider/context.ts),非常适合埋点上报或触发副作用。

快速参考

  • 完整状态与属性说明:README.md 的 API Reference 部分
  • 交互状态可运行的示例应用:example/app/index.tsx、example/app/screen.tsx
  • 状态行为的单元测试:src/tests/handlers.test.tsx

【免费下载链接】presstoYour React Native app deserves better tap interactions.项目地址: https://gitcode.com/gh_mirrors/pre/pressto

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/25 9:34:28

MoneyWallet日历视图与地图视图:你可能不知道的两个宝藏功能

MoneyWallet日历视图与地图视图:你可能不知道的两个宝藏功能 【免费下载链接】moneywallet An android application that let you track your expenses 项目地址: https://gitcode.com/gh_mirrors/mo/moneywallet MoneyWallet 是一款免费开源的 Android 记账…

作者头像 李华
网站建设 2026/8/25 9:31:05

数据库技术选型与面试实战指南

1. 面试中的数据库考察:为什么这个问题如此重要"你了解过哪些数据库?"这个问题几乎成了技术面试的必考题。作为从业多年的技术面试官,我见过太多候选人在这道看似简单的问题上栽跟头。实际上,这个问题背后考察的是你对数…

作者头像 李华
网站建设 2026/8/25 9:30:56

Java Serializable深度解析:契约、实践、安全与性能

1. 这个问题远不止“面试八股文”那么简单“Java中的实体类为什么要 implements Serializable?”——这句话我听过太多次了。刚入行那会儿,我在三线小城一家外包公司写CRUD,带我的老哥边敲键盘边说:“加个Serializable&#xff0c…

作者头像 李华
网站建设 2026/8/25 9:28:22

大模型训练岗校招火爆:技能要求与面试解析

1. 大模型训练岗为何成为校招"顶流"?2026年的校招季,大模型训练岗位毫无悬念地成为最炙手可热的选择。头部企业开出的180万年薪并非噱头,而是真实反映了行业对这类人才的渴求。作为亲历过三届校招的技术面试官,我发现这…

作者头像 李华
网站建设 2026/8/25 9:26:44

RTK Query 乐观更新实战:5步打造秒级响应的 React 界面

RTK Query 乐观更新实战:5步打造秒级响应的 React 界面 【免费下载链接】rtk-query Data fetching and caching addon for Redux Toolkit 项目地址: https://gitcode.com/gh_mirrors/rt/rtk-query 想让用户操作"零等待"吗?RTK Query 乐…

作者头像 李华