I'm trying to build a website for displaying real-time charts in typescript with react for my learning. But I can not get values from a server properly before displaying the chart.
What I want to do is ...
useSocket.tsx
) so as to access the data from any react components easily.Home.tsx
.initial_data
and new_data
.initial_data
event is received at the time the accessing the website at first.new_data
event is received at regularly.Home.tsx
automatically.I researched some articles on the web, for example, explaining a way that using socket.io
inside a useEffect()
function that returning socket.disconnect()
.
So, the code I built is below.
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>
</>
)
})
The above code caused an error Uncaught TypeError: Cannot read properties of undefined (reading '0')
occurred in the browser console. But when the comment out the <Heading>...</Heading>
line in Home.tsx
, the console.log
in useSocket.tsx
can display the value from the server in the browser console.
I can not come up with the idea for the correct implementation. Is the definition of the type of the chartData
wrong? or other reasons? The definition of the chartDataType
has nothing wrong.
What is the way for the correct implementation?
What's happening is you are trying to render an empty array, the data hasn't loaded yet.
You need to check if charData exists, or if it's undefined first.
Like this:
return (
{CharData ? <Heading /> ... : null }
)