如何在Redux Action中实现多动态链接WebSocket并区分币安数据Payload
解决币安WebSocket数据在Redux中区分币种的问题
你的核心问题是没有给每条WebSocket数据添加币种标识,导致Redux无法区分不同币种的payload,同时缺少合理的WebSocket实例管理和Redux状态结构设计。以下是具体的解决实现:
1. 修改Action Creator,给Payload添加币种标识
在dispatch时,把当前币种信息和数据一起传入payload,同时完善WebSocket的错误处理、实例管理和清理逻辑:
export function setupCoinSockets() { return function (dispatch: Dispatch) { // 存储socket实例,避免重复创建,方便后续关闭 const sockets: Record<string, WebSocket> = {}; coins.forEach(coin => { if (sockets[coin]) return; const socket = new WebSocket(`wss://stream.binance.com:9443/ws/${coin}@trade`); sockets[coin] = socket; socket.onmessage = (event) => { const tradeData = JSON.parse(event.data); dispatch({ type: "WEBSOCKET_TRADE_DATA", payload: { coin, // 新增币种标识 data: tradeData } }); }; // 错误处理 socket.onerror = (error) => { dispatch({ type: "WEBSOCKET_ERROR", payload: { coin, error } }); }; // 连接关闭时清理实例 socket.onclose = () => { delete sockets[coin]; // 可选:添加重连逻辑 }; }); // 返回清理函数,组件卸载时关闭所有socket,防止内存泄漏 return () => { Object.values(sockets).forEach(socket => socket.close()); }; }; }
2. 设计合理的Redux状态结构
使用对象以币种为key存储数据,确保不同币种的数据相互独立,便于视图层获取:
// 初始状态 const initialState = { tradeData: {}, // 结构:{ [币种名称: string]: 交易数据 } errors: {} // 存储各币种的连接错误 }; function webSocketReducer(state = initialState, action) { switch (action.type) { case "WEBSOCKET_TRADE_DATA": { const { coin, data } = action.payload; return { ...state, tradeData: { ...state.tradeData, [coin]: data // 用币种作为key,更新对应数据 } }; } case "WEBSOCKET_ERROR": { const { coin, error } = action.payload; return { ...state, errors: { ...state.errors, [coin]: error } }; } default: return state; } }
3. 视图层展示对应币种的数据
通过useSelector精准获取指定币种的交易数据:
import { useSelector } from "react-redux"; // 单个币种的展示组件 function CoinTradeCard({ coin }) { const tradeData = useSelector(state => state.webSocket.tradeData[coin]); if (!tradeData) return <div>加载中...</div>; return ( <div className="coin-card"> <h3>{coin.toUpperCase()}</h3> <p>最新成交价: {tradeData.p}</p> <p>成交量: {tradeData.q}</p> <p>交易时间: {new Date(tradeData.T).toLocaleString()}</p> </div> ); } // 批量展示所有币种 function AllCoinsDisplay() { return ( <div className="coins-container"> {coins.map(coin => ( <CoinTradeCard key={coin} coin={coin} /> ))} </div> ); }
关键优化点说明
- 币种标识绑定:每条payload都携带对应的币种名称,从根源解决数据混淆问题。
- 结构化状态存储:用对象key-value的方式管理多币种数据,查询和更新效率更高。
- WebSocket生命周期管理:保存实例避免重复连接,添加关闭清理和错误处理,防止内存泄漏。
内容的提问来源于stack exchange,提问作者AmirAli
相关产品推荐
相关产品推荐

