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

WebSocket数据读取'fs'属性报错,React图表渲染问题求助

WebSocket数据可视化图表报错解决

问题描述

通过WebSocket连接Python程序与React的App.js,实现数据曲线可视化。面板1模块可正常显示数据,但尝试将WebSocket数据中的data["fs"]["s1"]["twist"]插入图表时,出现错误:App.js:51 Uncaught TypeError: Cannot read property 'fs' of null。

已尝试方案

  • 在useEffect依赖数组中加入[data],导致界面频繁卡顿,WebSocket连接多次断开
  • 添加try-catch块,仍持续触发fs属性读取错误
  • 在socket的message事件监听中直接解析event.data传入图表可正常工作,但打印state中的data显示为null

错误原因

  1. 初始state中data为null,组件挂载时直接访问data["fs"]会触发空值报错
  2. useEffect内的图表更新逻辑写在socket监听外部,未等待数据更新就执行,此时data仍为初始的null
  3. 将[data]加入依赖会导致useEffect重复执行,每次创建新WebSocket连接,引发卡顿与连接断开

解决方案

修复步骤

  1. 在socket的message事件回调中直接处理解析后的数据,同步更新图表,避免依赖state的异步更新延迟
  2. 使用可选链操作符?.判断数据是否存在,确保访问深层属性前已有有效数据
  3. 保持WebSocket连接仅创建一次,组件卸载时关闭连接,避免重复连接

修改后的App.js代码

import React, { useState, useEffect } from 'react';
import Modal from './Modal/Modal'
import {Chart as ChartJS,LinearScale,PointElement,LineElement,Tooltip,Legend} from 'chart.js';
import {Scatter } from 'react-chartjs-2';
ChartJS.register(
    LinearScale,
    PointElement,
    LineElement,
    Tooltip,
    Legend);

export default function App() {
  const [data, setData] = useState(null);
  const [chartData,setChartData]=useState({
    datasets: [
        {
          label: 'A dataset',
          showLine:true,
          maintainAspectRatio:false,
          fill:false,
          data: [{x:3,y:1},{x:10,y:2},{x:5.5,y:3},{x:50,y:4},{x:5,y:5}],
          backgroundColor: 'rgba(255, 99, 132, 1)',
          borderColor: '#df9305'
        }]
    });
  const [show,setShow] = useState(false);

  const updateChart = (twistValue) => {
    const newData = [
      {x: twistValue, y: 1},
      {x:2,y:2},
      {x:5.5,y:3},
      {x:5,y:4},
      {x:5,y:5}
    ];
    setChartData(prev => ({
      ...prev,
      datasets: [{...prev.datasets[0], data: newData}]
    }));
  };
  
  useEffect(() => {
    const socket = new WebSocket('ws://localhost:8000');

    socket.addEventListener('message', (event) => {
      const parsedData = JSON.parse(event.data);
      setData(parsedData);
      // 直接用解析后的数据更新图表,无需等待state同步
      if (parsedData?.fs?.s1?.twist !== undefined) {
        updateChart(parsedData.fs.s1.twist);
      }
    });

    // 组件卸载时关闭WebSocket连接
    return () => {
      socket.close();
    };
  }, []);
  
  return (
        <div>
            <div className="home">
                <div className="template-1" id="temp1">
                    <div className="panel-1">
                    <div className="panel-header">
                    <h1>Foresail</h1>
                    <i className='bx bx-cog modal-trigger-panel'></i>
                    </div>
                    <div className="panel-body">
                    <div className="sec-5 modal-trigger-data" id="fs-sec-5" onClick={()=>setShow(true)}>
                        {data?.fs?.s5?.twist ?? <span class="h1" id="h1-fs-s5">--</span>}
                        <h2>TWIST</h2>
                        <h3>s5</h3>
                    </div>
                    <div className="sec-4 modal-trigger-data" id="fs-sec-4" onClick={()=>setShow(true)}>
                        {data?.fs?.s4?.twist ?? <span class="h1" id="h1-fs-s4">--</span>}
                        <h2>TWIST</h2>
                        <h3>s4</h3>
                    </div>
                    <div className="sec-3 modal-trigger-data" id="fs-sec-3" onClick={()=>setShow(true)}>
                        {data?.fs?.s3?.twist ?? <span class="h1" id="h1-fs-s3">--</span>}
                        <h2>TWIST</h2>
                        <h3>s3</h3>
                    </div>
                    <div className="sec-2 modal-trigger-data" id="fs-sec-2" onClick={()=>setShow(true)}>
                        {data?.fs?.s2?.twist ?? <span class="h1" id="h1-fs-s2">--</span>}
                        <h2>TWIST</h2>
                        <h3>s2</h3>
                    </div>
                    <div className="sec-1 modal-trigger-data" id="fs-sec-1" onClick={()=>setShow(true)}>
                        {data?.fs?.s1?.twist ?? <span class="h1" id="h1-fs-s1">--</span>}
                        <h2>TWIST</h2>
                        <h3>s1</h3>
                    </div>
                    </div>
                </div>

                <div class="panel-3">
                    <div class="panel-header">
                    <h1>Courbes</h1>
                    <i class='bx bx-cog modal-trigger-panel'></i>
                    </div>
                    <div class="panel-body">
                    <Scatter options={{showLines:true,legend:{display:false}}} data={chartData} />
                    </div>
                </div>
                
                </div>
                <Modal onClose={() => setShow(false)} show={show} />
            </div>
        </div> 
  );
}

Python代码无需修改

原Python的WebSocket服务逻辑正常,保持原样即可。

内容的提问来源于stack exchange,提问作者Feyto

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 03:55:18