同一个React组件中处理两个WebSocket请求数据渲染异常问题
问题根因
- 最初的报错是因为你在同一个JSON对象里重复定义了
keys、type、id字段,对象重复key会直接覆盖前面的内容,所以第一次发送的请求实际只有getMarket的参数,自然拿不到赛事信息 - 后续修改后的遍历报错,是因为
socketData里存储的是两个独立的消息对象,每个元素都是对象不是数组,不需要内层forEach遍历
正确实现代码
import { useState, useEffect } from 'react'; import socketConnection from '../../connection'; import NavBar from '../../../Component/NavBar'; const ws = socketConnection(); export default function GetEvent() { const [isLoading, setLoading] = useState(true); // 拆分两类数据状态,直接对应渲染字段,不需要额外遍历 const [eventData, setEventData] = useState(null); const [marketData, setMarketData] = useState(null); useEffect(() => { ws.onopen = () => { // 独立发送两个请求,不要合并到同一个对象里 ws.send( JSON.stringify({ keys: ['xyz'], type: 'getEvent', id: 111, }) ); ws.send( JSON.stringify({ keys: ['skd'], type: 'getMarket', id: 222 }) ); }; function handleMessage(event) { const parsedData = JSON.parse(event.data); // 根据返回的type字段分类存储数据 if (parsedData.type === 'EVENT_DATA') { setEventData(parsedData.data); } else if (parsedData.type === 'MARKET_DATA') { setMarketData(parsedData.data); } // 两类数据都返回后再关闭加载状态 setLoading(prev => { if (eventData && marketData) return false; return prev; }); } ws.addEventListener('message', handleMessage); return () => ws.removeEventListener('message', handleMessage); }, [eventData, marketData]); return ( <> <NavBar /> <div className="footyevent" data-testid="footy-event-id"> <div className="container"> <h1>Football</h1> <div className="title-box"> {isLoading && <div className="loading">加载中,请稍候</div>} </div> {/* 渲染赛事信息 */} {eventData && ( <> <div className="title-box"> <div className="startTime" data-testid="event-time-id"> 比赛时间: {eventData.date} </div> </div> <div className="title-box"> <div className="teams" data-testid="playing-teams-id"> 对阵双方: {eventData.name} </div> </div> </> )} {/* 渲染盘口信息 */} {marketData && ( <div className="title-box"> <div className="market" data-testid="market-data-id"> 盘口类型: {marketData.name} </div> </div> )} </div> </div> </> ); }
核心修改说明
- 拆分
eventData和marketData两个状态分别存储赛事和盘口数据,避免遍历数组找对应类型的冗余逻辑 - 收到消息时直接根据返回的
type字段分类存入对应状态,不需要额外遍历处理 - 加载状态等到两类数据都返回之后再关闭,避免页面部分渲染空白
- 渲染时直接判断对应状态是否存在,直接取字段渲染即可,不需要遍历整个消息数组
内容的提问来源于stack exchange,提问作者saint
相关产品推荐
相关产品推荐

