news 2026/8/23 12:52:06

如何让React吉他组件可交互:onChange与onPlay两大回调完整指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
如何让React吉他组件可交互:onChange与onPlay两大回调完整指南

如何让React吉他组件可交互:onChange与onPlay两大回调完整指南

【免费下载链接】react-guitarA beautiful and accessible guitar component for React. ⚛️ 🎸项目地址: https://gitcode.com/gh_mirrors/re/react-guitar

🎸react-guitar是一个为 React 打造的美观、可访问的吉他组件。本文是面向新手的onChange 与 onPlay 两大回调完整指南:讲清回调签名、触发时机与最小示例,帮你把一把"静态展示"的吉他快速变成可交互、能发声的吉他组件。

先搞懂核心数据:strings 数组

在配置回调之前,先理解吉他组件的"状态"——strings数组:

  • 数组中每个数字代表对应琴弦按压的品格,如[0, 1, 2, 2, 0, -1]就是标准调弦下的A 小调和弦
  • 0表示空弦,-1表示消音(不弹这根弦)
  • 默认从第 0 品开始、共 22 品,可用frets={{ from: 0, amount: 22 }}调整

这两个回调的签名在 packages/react-guitar/src/index.tsx 中定义:

回调签名作用
onChange(strings: number[]) => void琴弦被按下/松开时触发,不传则吉他只读
onPlay(string: number) => void每次"弹奏"某根弦时触发,用于播放声音

onChange 回调:让吉他从展示变可交互

触发时机

onChange会在用户点击品格、按方向键移动品位、或按 Enter 释放琴弦时触发,参数是更新后的完整strings数组。核心逻辑在 packages/react-guitar/src/index.tsx 的pressString中:每次按压都基于当前状态生成新数组并回调。

一个细节:组件内部会用disabled={!props.onChange}(见 packages/react-guitar/src/index.tsx)禁用交互——不传 onChange,吉他就是一张"静态图"

最小可用示例:可编辑吉他

useState保存当前按弦状态,把 setter 直接传给onChange即可(官方 Storybook 同款写法,见 storybook/index.stories.tsx):

import { useState } from 'react' import Guitar from 'react-guitar' function EditableGuitar() { const [strings, setStrings] = useState([0, 0, 0, 0, 0, 0]) return <Guitar strings={strings} onChange={setStrings} /> }

现在用户点击品格、用方向键移动手指都会实时更新 UI——这就是受控组件的标准套路。

onPlay 回调:让吉他"开口说话"

触发方式

onPlay(string)的参数是弦的索引(从 0 开始),有两种官方触发方式:

  • 🖱️鼠标悬停:给组件加上playOnHover属性,鼠标划过哪根弦就触发哪根弦(见 packages/react-guitar/src/index.tsx)
  • ⌨️键盘弹奏:聚焦到某根弦后按p键触发(见 packages/react-guitar/src/index.tsx)

💡 注意:onPlay不依赖onChange。即使吉他只读(固定展示一个和弦),也可以单独挂上onPlay让它发声——Storybook 中的 "with fixed A minor and sound" 示例就是这么做的(见 storybook/index.stories.tsx)。

搭配 useSound 自动发音

手动实现发音太麻烦,项目提供了配套包react-guitar-sounduseSoundHook(源码见 packages/react-guitar-sound/src/index.ts),它接收当前按弦状态和调弦,返回play(弹单弦)与strum(扫弦)两个函数:

import Guitar from 'react-guitar' import useSound from 'react-guitar-sound' import { standard } from 'react-guitar-tunings' function GuitarWithSound() { const strings = [0, 1, 2, 2, 0, -1] // 固定的 A 小调 const { play } = useSound({ fretting: strings, tuning: standard }) return <Guitar strings={strings} onPlay={play} /> }

调弦数据来自react-guitar-tunings包(packages/react-guitar-tunings/src/index.ts),内置标准调弦、Open G、DADGAD 等常见配置。默认音色是尼龙民谣吉他,也可以用withSoundFont('electric_guitar_clean')换成电吉他,或用withSamples({ E2: 'E2.mp3', ... })换成自己的采样。

组合使用:一把完整可交互的发声吉他

把两个回调一起接上,再开启playOnHover,就是官网 Demo 的完整形态(参考 site/components/Demo.tsx):

import { useState } from 'react' import Guitar from 'react-guitar' import useSound from 'react-guitar-sound' import { standard } from 'react-guitar-tunings' function InteractiveGuitar() { const [strings, setStrings] = useState([0, 0, 0, 0, 0, 0]) const { play } = useSound({ fretting: strings, tuning: standard }) return ( <Guitar strings={strings} onChange={setStrings} // 手指移动实时更新 onPlay={play} // 弹奏时发音 playOnHover // 鼠标悬停即发声 /> ) }

🎹 键盘党福利(官方 Demo 同款快捷键,见 site/hooks/sound.ts):

按键功能
1-6弹奏对应编号的琴弦
W/S上扫弦 / 下扫弦
方向键在琴弦与品位之间移动手指
P弹奏当前聚焦的琴弦
Enter释放(消音)当前琴弦

想换风格试试内置主题包react-guitar-theme-darkreact-guitar-theme-coco

常见问题快速解答

Q:只想要"能按",不需要声音?只传onChangestrings状态自己更新即可。Q:想让某根弦默认为消音?strings数组对应位置写-1,如[3, -1, 0, 2, 0, -1]Q:onPlay里能拿到当前按了几个品吗?不能,参数只有弦索引;当前品位请从自己维护的strings状态读取。Q:官方完整 Props 文档在哪看?见 packages/react-guitar/README.md 的 Props 表格。

小结

一句话记住两大回调的分工:

  • onChange(strings)—— 负责"手":把用户的按弦操作同步到你的状态,是吉他可交互的开关
  • onPlay(string)—— 负责"声":在弹奏事件发生时触发,配合useSound即可发音

按本文的最小示例把这两个回调接上,10 分钟就能做出一个可弹奏、可扫弦的 React 吉他组件。🎶

【免费下载链接】react-guitarA beautiful and accessible guitar component for React. ⚛️ 🎸项目地址: https://gitcode.com/gh_mirrors/re/react-guitar

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

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

人形机器人开发实战:从技术栈解析到仿真与实机部署

在实际机器人研发和工程落地过程中&#xff0c;人形机器人&#xff08;Humanoid Robot&#xff09;的“链主”角色正日益凸显。这里的“链主”并非指传统产业链的龙头企业&#xff0c;而是指在技术栈整合、核心零部件定义、软件算法迭代和场景验证闭环中&#xff0c;起到关键驱…

作者头像 李华
网站建设 2026/8/23 12:46:22

C++类模板中友元函数三种模式详解与实战避坑指南

1. 项目概述&#xff1a;当模板遇上友元&#xff0c;一场关于访问权限的精密设计 在C的模板编程世界里&#xff0c;我们常常醉心于构建泛型、可复用的数据结构与算法。然而&#xff0c;当这种泛型机制与另一个旨在打破封装壁垒的特性——“友元”相遇时&#xff0c;事情就变得微…

作者头像 李华
网站建设 2026/8/23 12:42:47

网络配置核心概念详解:IP地址、子网掩码、网关与DNS

很多朋友在配置网络、排查故障或者学习网络知识时&#xff0c;常常被IP地址、子网掩码、网关、DNS这些名词搞得晕头转向。它们就像网络世界的“身份证”、“门牌号”和“导航仪”&#xff0c;是计算机之间能够互相找到并通信的基础。今天&#xff0c;我们就来一次彻底讲透&…

作者头像 李华
网站建设 2026/8/23 12:37:53

开源投屏工具scrcpy:极简设计如何实现低延迟与双向交互

最近在折腾手机投屏到电脑&#xff0c;发现一个挺有意思的现象&#xff1a;很多人一提到 iOS 投屏&#xff0c;第一反应就是去找各种商业软件&#xff0c;或者忍受那些功能有限、广告满天飞的免费工具。直到我在 GitHub 上看到一个项目&#xff0c;它用一种近乎“朴素”的方式&…

作者头像 李华
网站建设 2026/8/23 12:36:23

Linux内核性能优化:Jump Labels与Static Keys原理与实践

1. 背景与核心概念 在 Linux 内核开发中&#xff0c;性能优化是一个永恒的话题。你是否遇到过这样的场景&#xff1a;内核中某个功能&#xff08;如调试信息打印、性能计数器、特定硬件支持&#xff09;在绝大多数情况下是关闭的&#xff0c;只有在特定条件下才需要启用。如果使…

作者头像 李华
网站建设 2026/8/23 12:35:17

数学建模竞赛实战指南:从认证杯A题看模型构建与论文写作全流程

1. 项目概述&#xff1a;从“认证杯A题”看数学建模竞赛的实战精髓 又到了一年一度的数学建模竞赛季&#xff0c;无论是“认证杯”、“美赛”还是“国赛”&#xff0c;拿到赛题的那一刻&#xff0c;总是几家欢喜几家愁。2022年十一届认证杯的A题&#xff0c;当时在圈内引起了不…

作者头像 李华