首页 > web前端 > js教程 > 在几分钟内将实时协作添加到您的 React 应用程序

在几分钟内将实时协作添加到您的 React 应用程序

Barbara Streisand
发布: 2025-01-03 20:56:40
原创
671 人浏览过

前几天,我认识的人发消息:

“我发现自己在假期里试图向我的儿子解释投资回报如何通过 Zoom 发挥作用,如果我们都能够在像 Google Doc 这样的东西中工作,事情就会变得很容易”

接受挑战!

在过去的几天里,我很高兴构建了一个投资回报模拟器,我们可以在其中根据多个参数预测投资回报。
互联网上到处都是这样的网站,但在这个网站中,我想探索如何嵌入协作功能,以及它们如何将人们聚集在一起

在本指南中,我们将了解如何在短短 10 分钟内向常规 React 应用程序添加实时协作,而无需编写任何后端代码或处理 Web 套接字。作为奖励,我们还将探索如何增强协作网站的用户体验!

该项目的完整源代码可在 GitHub 上获取

让我们开始吧!

起点:打好基础

在深入研究协作功能之前,我们需要坚实的基础。我首先创建了一个单人游戏版本,用户可以在其中输入他们的投资参数。然后,这些输入将输入计算引擎,生成并显示投资回报预测。

我使用 Bolt.new 来快速启动和运行。它给我的简洁设计以及我达到​​可接受起点的速度给我留下了深刻的印象。尽管领先了很多,但我仍然需要微调一些计算逻辑,并根据自己的喜好调整 UI。


使应用程序具有协作性

单人游戏版本完成后,我将注意力转向协作。这个项目提供了一个测试 React Together 的绝佳机会,React Together 是我过去几个月在 Multisynq 开发的一个开源库。

React Together 提供了挂钩和组件,可以实现协作功能,而无需设置后端或管理套接字连接的复杂性。事实证明,实施过程很简单,尽管它揭示了一些需要改进的地方,我们将在库的未来版本中解决这些问题。

现在,让我们逐步完成向我们的应用程序添加实时协作的三个步骤!启动你的计时器吗?

第 1 步:设置 React Together 上下文

第一步是将我们的应用程序包装在 React Together 上下文提供程序中。该组件在幕后处理所有状态同步和会话管理。

// src/index.tsx
import { StrictMode } from 'react'
import { ReactTogether } from 'react-together'
import { createRoot } from 'react-dom/client'
import App from './App.tsx'
import './index.css'

createRoot(document.getElementById('root')!).render(
  <StrictMode>
    <ReactTogether sessionParams={{
      appId: import.meta.env['VITE_APP_ID'],
      apiKey: import.meta.env['VITE_API_KEY'],
    }}>
      <App />
    </ReactTogether>
  </StrictMode>,
)
登录后复制
登录后复制
登录后复制
登录后复制

React Together 使用 Multisynq 的基础设施进行应用程序同步,这需要 API 密钥。您可以从 multisynq.io/account 获取免费 API 密钥。别担心,这些密钥应该是公开的,因为您可以控制哪些域可以使用它们。

我们可以将 React Together 配置为在所有用户进入网站后自动将他们连接到同一个会话。事实上,这将使其成为一个两步指南,但我采用了 Google Docs 风格的方法,其中协作是选择加入的。用户保持断开连接,直到通过单击按钮明确创建或加入会话。我们将在本指南的第三步介绍会话管理!

第 2 步:跨用户同步状态

设置好 React Together 后,下一步是同步用户之间的状态。这个过程非常简单:我们只需要将 React 的 useState 钩子替换为 React Together 的 useStateTogether 钩子即可。

useStateTogether 钩子的工作方式与 useState 类似,但需要一个额外的 rtKey 参数。此键唯一标识整个应用程序的状态,即使在 DOM 层次结构在视口之间可能不同的响应式布局中也能确保正确的同步。

以下是转换的外观:

// src/index.tsx
import { StrictMode } from 'react'
import { ReactTogether } from 'react-together'
import { createRoot } from 'react-dom/client'
import App from './App.tsx'
import './index.css'

createRoot(document.getElementById('root')!).render(
  <StrictMode>
    <ReactTogether sessionParams={{
      appId: import.meta.env['VITE_APP_ID'],
      apiKey: import.meta.env['VITE_API_KEY'],
    }}>
      <App />
    </ReactTogether>
  </StrictMode>,
)
登录后复制
登录后复制
登录后复制
登录后复制
// Before
import { useState } from 'react'

export default function Calculator() {
  const [startingAmount, setStartingAmount] = useState(20000);
  const [years, setYears] = useState(25);
  const [returnRate, setReturnRate] = useState(10);
  const [compoundFrequency, setCompoundFrequency] = useState("annually");
  const [additionalContribution, setAdditionalContribution] = useState(500);
  const [contributionTiming, setContributionTiming] = useState("beginning");
  const [contributionFrequency, setContributionFrequency] = useState("month");

  // ...
}
登录后复制

这种方法的优点在于应用程序可以继续像以前一样工作 - 唯一的区别是现在状态更新在所有连接的用户之间同步。

第3步:添加会话管理

最后一步是为用户添加一种创建、加入和离开协作会话的方式。我选择通过计算器上方的标题部分来实现这一点,使每个人都可以轻松看到会话控件。

Add Real-Time Collaboration to Your React App in Minutes

React Together 通过提供四个基本钩子使这一过程变得简单:

  • useIsTogether:告诉我们当前是否处于会话中
  • useCreateRandomSession:创建一个新的私有会话
  • useLeaveSession:与当前会话断开连接
  • useJoinUrl:提供可共享的 URL 供其他人加入

这是标头组件的简化版本(我刚刚删除了类名称):

// After
import { useStateTogether } from 'react-together'

export default function Calculator() {
  const [startingAmount, setStartingAmount] = useStateTogether("startingAmount", 20000);
  const [years, setYears] = useStateTogether("years", 25);
  const [returnRate, setReturnRate] = useStateTogether("returnRate", 10);
  const [compoundFrequency, setCompoundFrequency] = useStateTogether("compoundFrequency", "annually");
  const [additionalContribution, setAdditionalContribution] = useStateTogether("additionalContribution", 500);
  const [contributionTiming, setContributionTiming] = useStateTogether("contributionTiming", "beginning");
  const [contributionFrequency, setContributionFrequency] = useStateTogether("contributionFrequency", "month");

  // ...
}
登录后复制

通过此实施,用户现在只需单击一下即可启动协作会话。当有人使用共享 URL 加入时,他们将立即看到与其他人相同的状态,所有更改都会在所有参与者之间实时同步。

就是这样,很简单,而且很有效!而且你可以在 10 分钟内完成!!


增强协作体验

虽然基本同步运行良好,但感觉有些不对劲:页面上的元素正在“自行”更改,但没有表明是谁在进行更改。这是协作应用程序中的一个常见挑战,Google Docs 等工具通过显示其他用户正在查看和编辑的位置来解决这个问题。

真正的协作不仅仅是同步状态,还在于创造一种存在感。用户需要互相“看到”才能有效地协同工作。

我最初考虑实现共享光标,让用户看到彼此的鼠标指针。然而,这种方法给响应式 Web 应用程序带来了挑战:

  • 鼠标坐标在不同视口大小之间无法清晰映射
  • 光标位置通常缺乏上下文 - 不清楚为什么用户的光标位于特定位置
  • 光标位置的含义在不同的屏幕布局中可能会不明确

相反,我专注于我们真正希望通过用户存在实现的目标:

  1. 帮助用户感受到其他人积极参与
  2. 显示每个用户当前正在查看或编辑的元素

解决方案?突出显示用户正在交互的元素。这种方法更简单、更直观,并且在所有视口尺寸上都能可靠地工作。让我们看看如何在两个关键区域实现这一点:图表选项卡和输入字段。

将用户状态添加到图表选项卡

让我们从用户状态的简单实现开始:显示哪些用户正在查看每个图表选项卡。

Add Real-Time Collaboration to Your React App in Minutes

为此,我们需要一种特殊的共享状态,其中每个用户都可以拥有自己的值,并且其他人都可以看到。

React Together 通过 useStateTogetherWithPerUserValues 钩子准确地提供了我们所需要的东西(是的,这实在是太拗口了!)。此挂钩的工作原理与 useStateTogether 类似,但它不是共享单个值,而是允许每个用户拥有自己的值,并且对所有参与者都可见。该钩子返回三个元素:

  1. 当前用户的本地状态值
  2. 更新本地状态的函数
  3. 包含每个用户状态值的对象

以下是我们如何实现此功能以在选项卡旁边显示用户头像:

// src/index.tsx
import { StrictMode } from 'react'
import { ReactTogether } from 'react-together'
import { createRoot } from 'react-dom/client'
import App from './App.tsx'
import './index.css'

createRoot(document.getElementById('root')!).render(
  <StrictMode>
    <ReactTogether sessionParams={{
      appId: import.meta.env['VITE_APP_ID'],
      apiKey: import.meta.env['VITE_API_KEY'],
    }}>
      <App />
    </ReactTogether>
  </StrictMode>,
)
登录后复制
登录后复制
登录后复制
登录后复制

在上面的代码片段中,我们用 useStateTogetherWithPerUserValues 替换了 useState,应用程序再次像以前一样继续工作,但现在每个人都可以看到其他人的状态!然后我们只需要渲染我们刚刚获得的新信息即可。

此实现在每个选项卡旁边显示用户头像,从而清楚地显示哪些用户正在查看哪些图表。我们过滤掉当前用户的头像以避免冗余,因为用户不需要看到自己的状态指示器。

在输入字段中添加用户状态

向输入字段添加存在指示器遵循与前面的示例类似的模式,但有一个额外的要求:我们需要跟踪用户何时开始和停止编辑。幸运的是,Ant Design 的组件为此目的提供了必要的回调。

对于每个输入字段,我想要:

  1. 当其他人正在编辑时显示彩色边框
  2. 右上角显示编辑头像
  3. 在整个应用程序中保持每个用户的颜色一致

以下是我们如何使用 useStateTogetherWithPerUserValues 钩子来实现这一点:

// src/index.tsx
import { StrictMode } from 'react'
import { ReactTogether } from 'react-together'
import { createRoot } from 'react-dom/client'
import App from './App.tsx'
import './index.css'

createRoot(document.getElementById('root')!).render(
  <StrictMode>
    <ReactTogether sessionParams={{
      appId: import.meta.env['VITE_APP_ID'],
      apiKey: import.meta.env['VITE_API_KEY'],
    }}>
      <App />
    </ReactTogether>
  </StrictMode>,
)
登录后复制
登录后复制
登录后复制
登录后复制

虽然代码稍长,但原理很简单:我们只需要跟踪哪些用户正在编辑每个输入字段,然后渲染我们想要的可视化效果即可。

同样的方法适用于任何其他输入类型,例如下拉菜单和滑块!!

--

就是这样!有了这个完全协作的投资回报模拟器,我的朋友可以更轻松地向他的儿子解释 Zoom 上的投资回报如何发挥作用。任务完成! ✨

看到创建这种协作网站是多么容易,让我想知道当我们在线时,互联网如何让我们更加紧密地联系在一起......稍后会详细介绍!

希望您学到新的东西,如果您有任何反馈或问题,请随时与我们联系!!

编码愉快! ?

  • ?现场演示
  • ?‍?源代码
  • ?一起反应文档

以上是在几分钟内将实时协作添加到您的 React 应用程序的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:dev.to
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板