socket.io 广播不适用于 React
socket.io broadcasting not working with React
我目前正在尝试在后端的 Node.js 应用程序和前端的 React 应用程序之间建立连接。从前端到后端的连接似乎没有任何问题。不幸的是,另一方面,React 应用程序无法接受任何数据。
socket.on(...) 函数抛出错误:
dashboard.js:20 未捕获类型错误:无法读取 null 的属性(读取 'on')
我无法解释错误所在。
app.js(React应用的挂载点):
import React, { useEffect, useState } from 'react';
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
import io from 'socket.io-client';
import Dashboard from "./compontents/views/dashboard/dashboard";
function App() {
const [socket, setSocket] = useState(null);
useEffect(() => {
const newSocket = io(`http://${window.location.hostname}:8040`);
setSocket(newSocket);
return () => newSocket.close();
}, [setSocket]);
return (
<Router>
<div className="app">
<div className="app__view">
<Switch>
<Route exact path="/">
<Dashboard socket={socket} />
</Route>
</Switch>
</div>
</div>
</Router>
);
}
导出默认应用;
dashboard.js(子组件):
import React, { useEffect, useState } from 'react';
import { Link } from "react-router-dom";
import FeatherIcon from 'feather-icons-react';
import LargeButton from "../../buttons/largeButton/largeButton";
function Dashboard({ socket }) {
function toggleLight(type) {
if(type) {
// this function works fine
socket.emit("toggle light", type);
console.log(type);
}
}
useEffect(() => {
// this line is causing the error
socket.on('toggle button', (type) => {
console.log(type);
});
}, [socket]);
return(
<div className="view">
<div className="all">
<LargeButton icon="sun" text="Alles einschalten" event={toggleLight} />
<LargeButton icon="moon" text="Alles ausschalten" event={toggleLight} />
</div>
</div>
)
}
export default Dashboard;
您的 <Dashboard/>
组件似乎在套接字实例准备就绪之前就已安装。套接字连接是一个异步过程,因此您在使用它时必须牢记这一点。
尝试将您的 app.js 更改为:
import React, { useEffect, useState } from 'react';
import { BrowserRouter as Router, Switch, Route } from 'react-router-dom';
import io from 'socket.io-client';
import Dashboard from './compontents/views/dashboard/dashboard';
function App() {
const [socket, setSocket] = useState(null);
useEffect(() => {
const newSocket = io(`http://${window.location.hostname}:8040`);
setSocket(newSocket);
return () => newSocket.close();
}, [setSocket]);
if (!socket) {
// catch and show some loading screen
// while the socket connection gets ready
return <div>Loading...</div>;
}
return (
<Router>
<div className="app">
<div className="app__view">
<Switch>
<Route exact path="/">
<Dashboard socket={socket} />
</Route>
</Switch>
</div>
</div>
</Router>
);
}
我目前正在尝试在后端的 Node.js 应用程序和前端的 React 应用程序之间建立连接。从前端到后端的连接似乎没有任何问题。不幸的是,另一方面,React 应用程序无法接受任何数据。
socket.on(...) 函数抛出错误:
dashboard.js:20 未捕获类型错误:无法读取 null 的属性(读取 'on')
我无法解释错误所在。
app.js(React应用的挂载点):
import React, { useEffect, useState } from 'react';
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
import io from 'socket.io-client';
import Dashboard from "./compontents/views/dashboard/dashboard";
function App() {
const [socket, setSocket] = useState(null);
useEffect(() => {
const newSocket = io(`http://${window.location.hostname}:8040`);
setSocket(newSocket);
return () => newSocket.close();
}, [setSocket]);
return (
<Router>
<div className="app">
<div className="app__view">
<Switch>
<Route exact path="/">
<Dashboard socket={socket} />
</Route>
</Switch>
</div>
</div>
</Router>
);
}
导出默认应用;
dashboard.js(子组件):
import React, { useEffect, useState } from 'react';
import { Link } from "react-router-dom";
import FeatherIcon from 'feather-icons-react';
import LargeButton from "../../buttons/largeButton/largeButton";
function Dashboard({ socket }) {
function toggleLight(type) {
if(type) {
// this function works fine
socket.emit("toggle light", type);
console.log(type);
}
}
useEffect(() => {
// this line is causing the error
socket.on('toggle button', (type) => {
console.log(type);
});
}, [socket]);
return(
<div className="view">
<div className="all">
<LargeButton icon="sun" text="Alles einschalten" event={toggleLight} />
<LargeButton icon="moon" text="Alles ausschalten" event={toggleLight} />
</div>
</div>
)
}
export default Dashboard;
您的 <Dashboard/>
组件似乎在套接字实例准备就绪之前就已安装。套接字连接是一个异步过程,因此您在使用它时必须牢记这一点。
尝试将您的 app.js 更改为:
import React, { useEffect, useState } from 'react';
import { BrowserRouter as Router, Switch, Route } from 'react-router-dom';
import io from 'socket.io-client';
import Dashboard from './compontents/views/dashboard/dashboard';
function App() {
const [socket, setSocket] = useState(null);
useEffect(() => {
const newSocket = io(`http://${window.location.hostname}:8040`);
setSocket(newSocket);
return () => newSocket.close();
}, [setSocket]);
if (!socket) {
// catch and show some loading screen
// while the socket connection gets ready
return <div>Loading...</div>;
}
return (
<Router>
<div className="app">
<div className="app__view">
<Switch>
<Route exact path="/">
<Dashboard socket={socket} />
</Route>
</Switch>
</div>
</div>
</Router>
);
}