当前位置: 首页 > 知识库问答 >
问题:

使用套接字使用react获取数据的正确方法。木卫一

邹杰
2023-03-14

我没有找到任何关于如何从快速服务器获取数据的例子,使用socket.io.

现在我做了类似这样的事情:服务器。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)
  })
})

反应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)
    }
  }, [])

共有2个答案

呼延光明
2023-03-14

接受的答案有一个缺点,每次重新渲染时都会调用useRef()的初始状态。例如,对于文本输入,每次输入更改都会建立一个新的连接。我提出了两个解决方案:

  1. 在useEffect中定义套接字
const ChatInput = () => {
  const [chatMessage, setChatMessage] = useState<string>('');
  const socket = useRef<Socket>();

  useEffect(() => {
    socket.current = io('my api');
    socket.current.on('chat message', (message: string) => {
      setChatMessage(message);
    });
    return () => { socket.current?.disconnect(); };
  }, []);

  const inputHandler = (text: string) => {
    socket.current?.emit('chat message', text);
  };

  return (
    <View>
      <Text>{chatMessage}</Text>
      <TextInput onChangeText={(text) => inputHandler(text)} />
    </View>
  );
};
const ChatInput = () => {
  const [chatMessage, setChatMessage] = useState<string>('');
  const [socket] = useState(() => io('my api'));

  useEffect(() => {
    socket.on('chat message', (message: string) => {
      setChatMessage(message);
    });
    return () => { socket.disconnect(); };
  }, []);

  const inputHandler = (text: string) => {
    socket.emit('chat message', text);
  };

  return (
    <View>
      <Text>{chatMessage}</Text>
      <TextInput onChangeText={(text) => inputHandler(text)}/>
    </View>
  );
};

export default ChatInput;
任小云
2023-03-14

这看起来很好,但是有些事情你可以改进,比如在卸载之前断开套接字,并且不要让套接字成为状态的一部分(参考下面的代码示例)。

如果您对如何将现有代码移植到钩子感到困惑,请首先使用类编写组件,然后将一部分一部分地移植到钩子。您可以将此答案称为备忘单。

使用传统类,使用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() {
    ...
  }
}

然后,您可以将移植到此。socket使用useRef(它不需要是state的一部分,因为render()函数不需要它。因此useRef是一个更好的选择(尽管useState可能仍然工作)。

port通过使用use效应并传递一个空数组作为第二个参数,使效果回调仅在挂载上运行。

通过在use效应回调中返回一个回调函数,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 ...;
}
 类似资料:
  • 问题内容: 我是一个新用户,正在尝试此命令。 我得到这个错误 我知道这似乎是一个琐碎的问题,但我坚持下去。 问题答案: 如果编译和安装的代码是 不是 在分支(签出由默认值),但只有在该回购的分支,尝试: 然后重试编译。

  • 我从插座开始。io节点。js,我知道如何在本地发送消息和广播函数:-所有连接的客户端都接收相同的消息。 现在,我想知道如何向特定客户端发送私人消息,我的意思是两个人之间的私人聊天(客户端到客户端流)的一个套接字。谢谢。

  • 我一直在研究HandlerThread类,因为最初我使用的是一个简单的线程和处理程序,但是在Android中使用NetworkOnMainThreadException出现了一个裁剪器。 我似乎无法理解如何将套接字之类的东西引入到HandlerThread中,您可以在其中运行阻塞代码。但是您不能使用HandlerThread来实现这一点,因为您不应该覆盖run,因为这是循环器所在的位置。 而且我不

  • 问题内容: 我正在使用SentiWordNet做一些情绪分析,我在这里提到了如何使用SentiWordNet的帖子。但是,尽管尝试了各种输入,但我仍得到0.0分。我在这里做错什么了吗?谢谢! 这是SentiWordNet.txt的前10行 问题答案: 通常文件带有奇怪的格式。 您需要删除它的第一部分(包括注释和说明)和最后两行: 解析器不知道如何处理这些情况,如果删除这两行,就可以了。

  • 问题内容: 我知道使用urllib2来获取网页很容易,但是我想知道是否有使用套接字实现获取网页功能的示例,我在Google上搜索了很多,我没有在其中找到任何示例,请问有什么帮助吗? 问题答案: 这是我鞭打的东西。它不会捕获异常来处理错误。青年汽车

  • 问题内容: 这个想法是使用更少的连接和更好的性能。连接是否随时终止? 对于另一个问题,是否打开新连接? 问题答案: 不,多路复用器不会过期。没有GetDatabase不会打开新连接。basics.md涵盖了所有内容 -特别是: 从GetDatabase返回的对象是便宜的直通对象,不需要存储。