这看起来不错,但是您可以改进一些事情,例如在卸载之前断开套接字以及不使套接字成为状态的一部分(请参阅下面的代码示例)。
如果您对如何将现有代码移植到钩子感到困惑,请先使用类写出组件,然后将部分移植到钩子。您可以将此StackOverflow 答案称为备忘单。
使用传统类,使用 socket.io 看起来像:
class App extends React.Component {
constructor(props) {
super(props);
this.socket = io();
}
componentDidMount() {
this.socket.open();
this.socket.emit('load settings');
this.socket.on('settings is here', (data) => {
// we get settings data and can do something with it
this.setState({
settings: data,
})
});
}
componentWillUnmount() {
this.socket.close();
}
render() {
...
}
}
然后你可以移植this.socket
使用useRef
(它不需要state
成为你的render()
功能不需要它的一部分。所以useRef
是一个更好的选择(尽管useState
可能仍然有效)。
端口componentDidMount()
通过使用useEffect
并传递一个空数组作为第二个参数,以使效果回调仅在挂载时运行。
componentWillUnmount()
通过在回调中返回一个回调函数进行端口useEffect
,React 在卸载之前将调用该回调函数。
function App() {
const socketRef = useRef(null);
const [settings, setSettings] = useState(false);
useEffect(() => {
if (socketRef.current == null) {
socketRef.current = io();
}
const {current: socket} = socketRef;
try {
socket.open();
socket.emit('load settings');
socket.on('settings is here', (data) => {
// we get settings data and can do something with it
setSettings(data);
})
} catch (error) {
console.log(error);
}
// Return a callback to be run before unmount-ing.
return () => {
socket.close();
};
}, []); // Pass in an empty array to only run on mount.
return ...;
}