javascript - 使用 socket.io 获取数据的正确方法

标签 javascript reactjs express socket.io react-hooks

我没有找到任何关于如何使用 react with socket.io 从 express 服务器获取数据的示例。

现在我做这样的事情: 服务器.js

io.on('connection', socket => {
  console.log(socket.id)

  socket.on('disconnect', () => {
    console.log(socket.id + ' disconnected')
  })

  socket.on('load settings', () => {
    socket.emit('settings is here', data)
  })
})

react .js

const [socket] = useState(io())
  const [settings, setSettings] = useState(false)

   useEffect(() => {
    try {
      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)
    }
  }, [])

最佳答案

这看起来不错,但有些地方您可以改进,例如在卸载之前断开套接字,并且不使套接字成为状态的一部分(请参阅下面的代码示例)。

如果您对如何将现有代码移植到 Hook 感到困惑,请先使用类编写组件,然后逐个移植到 Hook 。你可以引用这个StackOverflow answer作为备忘单。

使用传统的类,使用 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 可能仍然有效)。

通过使用 useEffect 移植 componentDidMount() 并传递一个空数组作为第二个参数,使效果回调仅在挂载时运行。

端口 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 ...;
}

关于javascript - 使用 socket.io 获取数据的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53383316/

相关文章:

javascript - 在 JavaScript 中转义 querySelector 的前导数字类名

javascript - 音量 slider 在单击时正确播放音频文件,但未更改同一元素的按键音量

javascript - Express.js 意外的 'GET' 到 '/json/version'

javascript - Node 无法读取未定义的属性 'forEach'

javascript - 通过 jQuery 一次播放和暂停一个 HTML5 音频元素

javascript - 在 Javascript 中扩展对象

javascript - 以 redux-form 形式添加多个 <Fields/>

reactjs - Firebase 云消息传递在窗口焦点之外时不显示通知

javascript - React 的工作流程是什么

node.js - '{}' 类型缺少 'Request' : get, 类型 header 、accepts、acceptsCharsets 和 67 个其他属性中的以下属性