使用 react.context 和 socket.io 反应实时图表

React real-time chart with react.context and socket.io

我正在尝试建立一个网站,用于在打字稿中显示实时图表,并做出反应以供我学习。但是在显示图表之前我无法从服务器正确获取值。

我想做的是...

  1. 通信协议为websocket,使用socket.io。
  2. 使用 socket.io 和存储数据在 React.Context(useSocket.tsx) 中,以便轻松访问来自任何 React 组件的数据。
  3. 显示数据在Home.tsx
  4. 套接字事件是initial_datanew_data
  5. 第一次访问网站时收到initial_data事件
  6. 定期收到 new_data 事件。
  7. 获取以上两个事件的时间,自动更新Home.tsx内的值。

我在网上研究了一些文章,例如,解释了在返回 socket.disconnect().
useEffect() 函数中使用 socket.io 的方法 所以,我构建的代码如下。

useSocket.tsx

import {useContext, createContext, useState, useEffect} from "react";
import {io, Socket} from "socket.io-client";
import {chartDataType} from "../types/chartDataType";

type Context = {
    chartData: Array<chartDataType>;
}

const SocketContext = createContext<Context>({
    chartData: [],
});

const SocketsProvider = (props: any) => {

    const [chartData, setChartData] = useState();

    useEffect( () => {
        const socket: Socket = io("http://***.***.***.***");

        socket.on('initial_data', (data) => {
            console.log(data);
            setChartData(data);
        });

        socket.on('new_data', (data) => {
            console.log(data);
        });

        return () => { socket.disconnect() };
    },[]);

    return (
        <SocketContext.Provider value={{chartData}} {...props} />
    );
}

const useSocket = () => useContext(SocketContext);

export { SocketsProvider, useSocket };

Home.tsx

import {memo, VFC} from "react";
import { useSocket } from "../../context/useSocket";
import {Heading} from "@chakra-ui/react";

export const Home: VFC = memo(() => {
    const { chartData } = useSocket();

    return (
        <>
            <Heading as="h1">{`${chartData}`}</Heading>
        </>
    )
})

以上代码导致浏览器控制台发生错误Uncaught TypeError: Cannot read properties of undefined (reading '0')。但是当注释掉Home.tsx中的<Heading>...</Heading>行时,useSocket.tsx中的console.log可以在浏览器控制台中显示来自服务器的值。

我想不出正确实施的想法。是不是chartData的类型定义有误?还是其他原因? chartDataType的定义没有错。
正确的实现方式是什么?

这是怎么回事,您正在尝试呈现一个空数组,数据尚未加载。

您需要先检查charData是否存在,或者是否未定义。

像这样:

return ( 
   {CharData ? <Heading /> ... : null }
)