前幾天,我認識的人傳訊息:
「我發現自己在假期裡試圖向我的兒子解釋投資回報如何透過 Zoom 發揮作用,如果我們都能夠在像 Google Doc 這樣的東西中工作,事情就會變得很容易」
接受挑戰!
在過去的幾天裡,我很高興建立了一個投資回報模擬器,我們可以在其中根據多個參數預測投資回報。
網路上到處都是這樣的網站,但在這個網站中,我想探索如何嵌入協作功能,以及它們如何將人們聚集在一起。
在本指南中,我們將了解如何在短短 10 分鐘內為常規 React 應用程式添加即時協作,而無需編寫任何後端程式碼或處理 Web 套接字。作為獎勵,我們也將探索如何增強協作網站的使用者體驗!
專案的完整原始碼可在 GitHub 上取得
讓我們開始吧!
在深入研究協作功能之前,我們需要堅實的基礎。我首先創建了一個單人遊戲版本,用戶可以在其中輸入他們的投資參數。然後,這些輸入將輸入計算引擎,產生並顯示投資回報預測。
我使用 Bolt.new 來快速啟動和運行。它給我的簡潔設計以及我達到可接受起點的速度給我留下了深刻的印象。儘管領先了很多,但我仍然需要微調一些計算邏輯,並根據自己的喜好調整 UI。
單人遊戲版本完成後,我將注意力轉向協作。這個專案提供了一個測試 React Together 的絕佳機會,React Together 是我過去幾個月在 Multisynq 開發的開源程式庫。
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 風格的方法,其中協作是選擇加入的。使用者保持斷開連接,直到透過點擊按鈕明確建立或加入會話。我們將在本指南的第三步介紹會話管理!
設定好 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"); // ... }
這種方法的優點在於應用程式可以繼續像以前一樣工作 - 唯一的區別是現在狀態更新在所有連接的使用者之間同步。
最後一步是為使用者新增一種建立、加入和離開協作會話的方式。我選擇透過計算器上方的標題部分來實現這一點,使每個人都可以輕鬆看到會話控制項。
React Together 透過提供四個基本鉤子使這個過程變得簡單:
這是標頭組件的簡化版本(我剛剛刪除了類別名稱):
// 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 應用程式帶來了挑戰:
相反,我專注於我們真正希望透過使用者存在實現的目標:
解決方案?突出顯示使用者正在互動的元素。這種方法更簡單、更直觀,並且在所有視窗尺寸上都能可靠地工作。讓我們看看如何在兩個關鍵區域實現這一點:圖表標籤和輸入欄位。
讓我們從使用者狀態的簡單實作開始:顯示哪些使用者正在查看每個圖表標籤。
為此,我們需要一種特殊的共享狀態,其中每個用戶都可以擁有自己的值,並且其他人都可以看到。
React Together 透過 useStateTogetherWithPerUserValues 鉤子準確地提供了我們所需要的東西(是的,這實在是太拗口了!)。此掛鉤的工作原理與 useStateTogether 類似,但它不是共用單一值,而是允許每個使用者擁有自己的值,並且對所有參與者都可見。此鉤子回傳三個元素:
以下是我們如何實現此功能以在選項卡旁邊顯示使用者頭像:
// 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 的組件為此目的提供了必要的回呼。
對於每個輸入字段,我想要:
以下是我們如何使用 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中文網其他相關文章!