You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

同一个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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 08:39:04