跳至主要內容
Skip to content

前端狀態管理:WebSocket 與 Pinia/React Hooks 同步

在 WebSocket 驅動的應用(如虛擬貨幣交易所、多人協作工具)中,數據是流動的持續更新。本章我們將探討如何建立一套「響應式」的實時數據流。


一、 核心架構:單向數據流

不要在 UI 組件中直接管理 WebSocket 連線。理想的架構應該是: WebSocket Server -> Store (Pinia/Redux) -> UI Components


二、 實務演練:Pinia 實時 Store 封裝 (Vue 3)

我們利用 Pinia 的組合式 API,將 WebSocket 訊息與 Store 狀態深度綁定。

Pinia Store 實作

javascript
export const useChatStore = defineStore("chat", () => {
  const messages = ref([]);
  let socket = null;

  function initConnection() {
    socket = new WebSocket("ws://localhost:8080");
    socket.onmessage = (event) => {
      const data = JSON.parse(event.data);
      messages.value.push(data.payload);
    };
  }

  return { messages, initConnection };
});

三、 React 視角:UseWS Hook

在 React 中,我們通常會封裝自定義 Hook:

javascript
function useWebSocket(url) {
  const [data, setData] = useState(null);
  useEffect(() => {
    const ws = new WebSocket(url);
    ws.onmessage = (e) => setData(JSON.parse(e.data));
    return () => ws.close();
  }, [url]);
  return data;
}

總結

實時數據的狀態管理關鍵在於「解耦」。讓連線邏輯待在它的專屬 Store 中,UI 只需要關注數據的展示。

下一章,我們將解鎖 SSE 與 WebTransport:不同實時技術的抉擇場景。


️ 進階挑戰

  1. 實作挑戰:為 useChatStore 加入數據緩衝區(Buffer),實現每 200ms 批量更新一次 UI。
  2. 效能思考:在 Vue/React 中,如果 messages 陣列長度達到 10,000 筆,我們該如何結合「虛擬列表 (Virtual List)」來處理?

延伸閱讀與資源