发布于 2026-01-06 0 阅读
0

我是如何构建 HypeBeats 的——一个使用 React 和 GraphQL hooks 的实时协作式 Beatbox 鼓机

我是如何构建 HypeBeats 的——一个使用 React 和 GraphQL 的实时协作 Beatbox

钩子鼓机

要查看实时演示,请点击这里
要查看代码仓库,请点击这里


最近我一直在研究 GraphQL 订阅,给应用程序添加实时功能,使其更具交互性。上周,我发布了一个使用react-canvas-draw 的实时绘图应用程序:

几周前,我在 React NYC 大会上看到一个关于使用 React Hooks 构建 beatbox 的演讲。

看完之后我非常兴奋。然后我找到了它的代码仓库,克隆了它,开始思考我能做些什么来让它更有趣。

GitHub 标志 肯惠勒/钩鼓机

React Day Berlin 演示

钩子鼓机

使用 React Hooks 构建的简单步骤序列器

如何跳skrrt

  • 跑步npm start
  • 酷毙了



鼓机基本上包含各种各样的节奏(低音、拍手、军鼓等),这些节奏通过步进音​​序器运行:

使用步进音序器,您可以按顺序从左到右移动,逐个遍历序列中的每个项目。如果某个项目被选中,则会播放与之关联的声音。

鼓机为我们提供了一个初始的节拍状态,音序器中的每个节拍都对应一个数组:

如果节拍设置为 0,则不播放(不高亮显示);如果设置为 1(高亮显示),则播放;如果设置为 2(闪烁),则播放三遍。

要了解鼓机内部的工作原理,请点击此处观看视频。

利用 GraphQL 订阅实现协作和实时性

我的想法是打造一个协作平台。为此,我需要添加创建和分享独特鼓机的功能。用户可以实时更新/修改鼓机,所有鼓机上的音乐都会随之更新。

为此,我需要做三件主要事情:

  1. 让鼓机动起来
  2. 添加路由
  3. 添加实时功能,理想情况下是 GraphQL 订阅。

为了使鼓机动态化并添加订阅功能,我创建了一个基本的 GraphQL schema 来保存我使用 AWS AppSync 部署的鼓机:

type Beatbox @model {
  id: ID!
  clientId: ID!
  beats: String!
  name: String!
}
Enter fullscreen mode Exit fullscreen mode

因为鼓机的状态是一个基本的 JSON 对象,所以我认为我们可以stringify很轻松地获取数据并将其存储在我们的数据库中。

我需要考虑的另一件事是路由。为此,我使用了React Router,并设计了一个如下所示的路由方案:

/machine/:id/:name
Enter fullscreen mode Exit fullscreen mode

除了节拍数据之外,每台鼓机都有一个独特的id属性,name我们可以利用这个属性来识别它并进行查询。

此外,还有一个clientId用于处理订阅数据的机制,使我们能够在客户端过滤掉重复项。

例如,当用户到达该路线时:

/machine/d562581d-2a2d-4597-a6bb-2580deaf0254/BassLord
Enter fullscreen mode Exit fullscreen mode

我们解析 URL 并检索机器名称和 ID。

我们在用户界面中使用机器名称,并使用机器 ID 来创建或查询机器。

当用户进行更改时,我们会触发 API 的更新:

// DrumMachine.js
async function updateBeatbox(beats, machineId) {
  const beatbox = {
    id: machineId, clientId, beats: JSON.stringify(beats)
  }
  try {
    await API.graphql(graphqlOperation(UpdateBeatbox, { input: beatbox }))
    console.log('successfully updated beatbox...')
  } catch (err) {
    console.log('error updating beatbox...:', err)
  }
  return () => {}
}
Enter fullscreen mode Exit fullscreen mode

该方法在Step.jsupdateBeatBox中调用

我们还创建了一个订阅来监听 GraphQL API 的更新:

// DrumMachine.js
useEffect(() => {
  const subscriber = API.graphql(graphqlOperation(onUpdateBeatbox)).subscribe({
    next: data => {
      const { value: { data: { onUpdateBeatbox: { clientId: ClientId, beats }}}} = data
      if (ClientId === clientId) return
      setSteps(JSON.parse(beats))
    }
  });
  return () => subscriber.unsubscribe()
}, []);
Enter fullscreen mode Exit fullscreen mode

除此之外,我基本上就是直接使用了鼓机的现有功能!

要查看实时演示,请点击这里
要查看代码仓库,请点击这里

贡献/后续步骤

接下来我想做的就是添加更多节拍!我还想添加一些其他音效。如果您想为此做出贡献,欢迎随时联系我提交 pull request
如果您想自行部署此应用程序,请查看仓库中的文档以快速上手。


我叫纳德·达比特 (Nader Dabit)。我是亚马逊云服务 (AWS) 的一名开发者布道师,负责AWS AppSyncAWS Amplify等项目。我专注于跨平台和云应用开发。

文章来源:https://dev.to/dabit3/how-i-built-hypebeats---a-real-time-collaborative-beatbox-with-react-graphql-29i5