我试图使用Node和Socket.IO创建一个ReactJS实时应用程序,但是我很难找到在客户端处理套接字连接的最佳方法。
我有多个React组件,都需要来自服务器的一些信息,最好通过套接字连接实时。但是当导入socket.io-client
依赖关系并在不同文件中建立与服务器的连接时,我会获得与服务器的多个连接,这看起来并不是最佳的。
因此,我想知道是否有更好的解决方案来共享多个组件之间的连接,而无需为每个组件创建新连接。也许通过在主app.js
文件中建立连接,然后将其传递给子组件以供以后使用。
网上有些地方建议使用context
属性来传递套接字变量,但是React自己的文档highly discourage the use of context。
以下代码只是一个示例,而不是实际代码,因为实际项目中的代码比说明问题所需的代码要多得多。
foo.js
import React from 'react';
import io from 'socket.io-client';
const socket = io("http://localhost:3000");
class Foo extends React.Component {
// ...
componentDidMount() {
socket.on("GetFooData", (data) => {
this.setState({
fooData: data
});
});
}
// ...
}
bar.js
import React from 'react';
import io from 'socket.io-client';
const socket = io("http://localhost:3000");
class Bar extends React.Component {
// ...
componentDidMount() {
socket.on("GetBarData", (data) => {
this.setState({
barData: data
});
});
}
// ...
}
app.js
import React from 'react';
import ReactDOM from 'react-dom';
import Foo from './foo';
import Bar from './bar';
const App = () => {
return (
<div className="container">
<Foo />
<Bar />
</div>
);
};
ReactDOM.render(
<App />,
document.getElementById("root")
);
答案 0 :(得分:2)
您可以创建一个套接字连接,然后像这样导出它,
import io from "socket.io-client";
let socket = io("http://localhost:8000/chat");
export default socket;
然后将其导入任何地方
import socket from "../../socket/socket";
答案 1 :(得分:1)
旧问题,但让我为Google员工回答。
我也在考虑上下文,但是去通过它作为道具,但是发生了一个问题,由于反应路线,我实际上无法按照我想要的方式传递它。路由道具(例如重定向历史记录)不起作用,或者套接字连接未通过。
因此,解决方案实际上是将socket变量作为道具传递,但结构有所不同。如果您使用的是路线,则会添加其他内容。实际上,您实际上需要以一种不同的方式呈现组件。
对我来说,这段代码
<Route path="/game" component={Game} />} />
更改为
<Route path="/game" render={(props) => <Game {...props} socket={this.state.socket} />} />
对于连接套接字,我像这样在componentWillMount内部完成。
constructor(props) {
super(props);
this.state = {
socket: false,
}
}
componentWillMount() {
let socket = io("http://localhost:5000");
this.setState({socket});
}
编辑:很显然,这并不是最好的方法,当通过套接字连接时,有些东西根本无法工作,例如套接字和express之间的相同会话。