我是一个初学者,编程的Javascript/类型抄本,并即将开发我的第一个应用程序的反应。为了从后端(FastAPI)获得一些数据,我创建了一个函数"GetData“,该函数在单击按钮时执行。
组件1:从"./socket“按钮导入{ GetData }
export default function Button() {
return (
<button onClick={GetData}>
Run
</button>
)
}组件2(命名套接字):websocket和数据逻辑
import {useState, createContext} from 'react';
let socket: any;
export async function ConnectWebsocket() {
socket = new WebSocket("ws://127.0.0.1:8000/");
socket.onopen = () => {
console.log('connected')
}
socket.onclose = () => {
console.log('closed')
}
socket.onerror = () => {
console.log('error')
}
}
export async function GetData() {
const [data, setData] = useState({});
socket.send("get Data");
socket.onmessage = (event: any) => {
const newData = JSON.parse(event.data);
console.log(`Data from server: ${newData}`);
setData((data) => ({ ...data, ...newData }));
}
console.log(`Overall data: ${data}`);
}我面临的问题是useState钩子。每当我试图通过websocket通过点击Run-Button来流数据时,我总是会得到以下错误:
未登录(承诺)错误:无效钩子调用。钩子只能在函数组件的主体内调用。这种情况的发生有以下原因之一:
我还创建了一个使用useState钩子的小例子,这个例子起了作用。你能看出我在上面的代码中搞错了什么吗?
另外,我还有一个初学者的问题。您将如何使“数据”变量可用于第三个组件(例如,表)?
发布于 2022-01-06 20:27:04
您只能在实际的react组件中使用react钩子。在您的例子中,Button组件。所以我会做这样的事情:
class SocketHelper {
socket = new WebSocket("ws://127.0.0.1:8000/");
constructor() {
socket.onopen = () => {
console.log('connected')
}
socket.onclose = () => {
console.log('closed')
}
socket.onerror = () => {
console.log('error')
}
}
}
export const socketHelper = new SocketHelper();
export default function Button() {
const [data, setData] = useState({});
useEffect(() => {
socketHelper.socket.onmessage = (event: any) => {
const newData = JSON.parse(event.data);
console.log(`Data from server: ${newData}`);
setData((data) => ({ ...data, ...newData }));
}
}, []);
const getData = () => {
socketHelper.socket.emit("getdata");
}
return (
<div>
<button onClick={getData}>
Run
</button>
<pre>{JSON.stringify(data, null, 2)}</pre>
</div>
)
}另外,您使用的是socket.send,但似乎不使用返回的套接字。因此,我将使用emit函数:https://socket.io/docs/v4/client-api/#socketemiteventname-args
https://stackoverflow.com/questions/70613002
复制相似问题