reactjs 无法从WebSocket接收的数据中读取属性?

2w3rbyxf  于 2023-01-17  发布在  React
关注(0)|答案(2)|浏览(133)

我试着添加曲线来可视化通过websocket连接到app.js程序的python程序的数据,通过websocket可以很好地检索数据,因为它连续显示在面板1的框中。
当我设置固定值时,面板中的图形显示良好,但当我想从websocket数据插入data["fs"]["s1"]["twist"]时,我得到以下错误:App.js:51 Uncaught TypeError: Cannot read property 'fs' of nul at WebSocket.<anonymous> (App.js:51)

    • 我尝试过的**:

我试过在useeffect函数中放入[data],但这使得显示错误(数据显示频率很高),与websocket服务器的连接中断了好几次。
我还在app.js文件中添加了一个try,catch来查看data是否为null,这个代码块对于fs属性始终返回相同的错误。
我在socket.addEventListener中添加了以下代码行,它可以正常工作:da=[{x:JSON.parse(event.data)["fs"]["s1"]["twist"],y:1},{x:JSON.parse(event.data)["fs"]["s2"]["twist"],y:2},{x:5.5,y:3},{x:5,y:4},{x:5,y:5}]; chart(da)
但是当我添加行console.log(data)时,它在控制台中打印null

    • 问题**:

如何获取数据并将其正确插入图表而不出错?
下面是代码:

    • 巨蟒**:
import asyncio
import random
import datetime
import websockets
import json

sv={"fs":{
    "s5":{"entry":2,"cfwd":3,"camber":2,"draft":3,"caft":5,"exit":5,"twist":15,"sag_lat":10,"sag_long":10},
    "s4":{"entry":2,"cfwd":3,"camber":2,"draft":3,"caft":5,"exit":5,"twist":15,"sag_lat":10,"sag_long":10},
    "s3":{"entry":2,"cfwd":3,"camber":2,"draft":3,"caft":5,"exit":5,"twist":15,"sag_lat":10,"sag_long":10},
    "s2":{"entry":2,"cfwd":3,"camber":2,"draft":3,"caft":5,"exit":5,"twist":15,"sag_lat":10,"sag_long":10},
    "s1":{"entry":2,"cfwd":3,"camber":2,"draft":3,"caft":5,"exit":5,"twist":15,"sag_lat":10,"sag_long":10},
    },
    "ms":{
    "s5":{"entry":2,"cfwd":3,"camber":2,"draft":3,"caft":5,"exit":5,"twist":15,"sag_lat":10,"sag_long":10},
    "s4":{"entry":2,"cfwd":3,"camber":2,"draft":3,"caft":5,"exit":5,"twist":15,"sag_lat":10,"sag_long":10},
    "s3":{"entry":2,"cfwd":3,"camber":2,"draft":3,"caft":5,"exit":5,"twist":15,"sag_lat":10,"sag_long":10},
    "s2":{"entry":2,"cfwd":3,"camber":2,"draft":3,"caft":5,"exit":5,"twist":15,"sag_lat":10,"sag_long":10},
    "s1":{"entry":2,"cfwd":3,"camber":2,"draft":3,"caft":5,"exit":5,"twist":15,"sag_lat":10,"sag_long":10},    
    }}

async def handler(websocket, path):
    while True:
        #log_decoder()
        for key1 in sv:
            for key2 in sv[key1]:
                sv[key1][key2]["entry"] = random.randint(1, 10)
                sv[key1][key2]["cfwd"] = random.randint(1, 10)
                sv[key1][key2]["camber"] = random.randint(1, 10)
                sv[key1][key2]["draft"] = random.randint(1, 10)
                sv[key1][key2]["caft"] = random.randint(1, 10)
                sv[key1][key2]["exit"] = random.randint(1, 10)
                sv[key1][key2]["twist"] = random.randint(1, 10)
                sv[key1][key2]["sag_lat"] = random.randint(1, 10)
                sv[key1][key2]["sag_long"] = random.randint(1, 10)        
        #data = [random.randint(0, 20) for _ in range(10)]
        await websocket.send(json.dumps(sv))
        await asyncio.sleep(1)

start_server = websockets.serve(handler, "localhost", 8000)

asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()
    • 应用程序js**:
import React, { useState, useEffect, useRef, useSyncExternalStore } 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);
//JSON.parse(event.data)
//<Doughnut ref={chartReference} data={data} />

export default function App() {
  let da;
  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 chart=(d) =>{
    setChartData({
        datasets: [
            {
              label: 'A dataset',
              showLine:true,
              maintainAspectRatio:false,
              fill:false,
              data: d,
              backgroundColor: 'rgba(255, 99, 132, 1)',
              borderColor: '#df9305'
            }]
    });
  };
  
  useEffect(() => {
    const socket = new WebSocket('ws://localhost:8000');

    socket.addEventListener('message', (event) => {
      setData(JSON.parse(event.data));
});
try {
        let twist = data["fs"]["s1"]["twist"];
        // use the twist variable to update 
        
        da=[{x:data["fs"]["s1"]["twist"],y:1},{x:2,y:2},{x:5.5,y:3},{x:5,y:4},{x:5,y:5}];
        chart(da)
      } catch (err) {
        // handle the error or show a default 
       console.log(err)
      }
  }, []);
  
  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 ? <span class="h1" id="h1-fs-s5">{data["fs"]["s5"]["twist"]}</span> : <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 ? <span class="h1" id="h1-fs-s4">{data["fs"]["s4"]["twist"]}</span> : <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 ? <span class="h1" id="h1-fs-s3">{data["fs"]["s3"]["twist"]}</span> : <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 ? <span class="h1" id="h1-fs-s2">{data["fs"]["s2"]["twist"]}</span> : <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 ? <span class="h1" id="h1-fs-s1">{data["fs"]["s1"]["twist"]}</span> : <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> 
  );
}

Regards,
iszxjhcz

iszxjhcz1#

发生错误的原因似乎是在您尝试访问“fs”属性时“data”变量未定义或为空。要修复此问题,在尝试访问“fs”属性之前,您可以检查“data”变量是否已定义且不为空。您可以使用if语句来检查“data”变量是否已定义且不为空,然后尝试访问“fs”属性。另外,你可以尝试使用try-catch块来处理错误,防止它使程序崩溃。下面是一个例子来说明你是如何做到这一点的:

if (data && data["fs"] && data["fs"] 
["s1"]) {
    let twist = data["fs"]["s1"] 
 ["twist"];
    // use the twist variable to update 
 your chart
} else {
    // handle the error or show a default 
value for the chart
}

或者

try {
  let twist = data["fs"]["s1"]["twist"];
  // use the twist variable to update 
  your chart
} catch (err) {
  // handle the error or show a default 
 value for the chart
}

还值得注意的是,您应该确保数据被正确地传递到app.js文件,并且数据的结构是正确的。

rslzwgfq

rslzwgfq2#

有可能问题不在于传递的数据,而在于app.js文件中处理数据的方式。错误消息表明,当您尝试访问“fs”属性时,“data”变量为空。一个可能的原因是app.js文件中的“data”变量设置不正确。
我建议检查以下内容:
确保从WebSocket消息中正确设置了“data”变量。您可以通过添加控制台日志语句来检查这一点,以便在收到websocket消息时打印“data”的值。
确保useEffect函数中正确引用了“data”变量。有可能您引用了错误的变量。
确保在useEffect函数中正确引用了“data”变量。您还可以检查data的值是否正确传递给useEffect函数
请确保数据结构与预期的数据结构相同。如果数据结构不同,则可能导致“data”变量上不存在“fs”属性。

相关问题