javascript - 使用 socket.io 事件更新状态
问题描述
我有一个反应功能组件:
function Chat(props) {
const [messages, setMessages] = useState([]);
const inputRef = useRef();
//The socket is a module that exports the actual socket.io socket
socket.socket.on("chatMessage", (msg) => {
setMessages([...messages, msg]);
});
const inputChanged = (e) => {
if (e.key === "Enter") {
socket.sendMessage(inputRef.current.value)
.then(() => {
//do something
})
.catch(console.log);
inputRef.current.value = "";
}
};
return (
<div>
{messages.map((msg, i) => <ChatMessage key={i}>{msg}</ChatMessage>)}
<input ref={inputRef} onKeyPress={inputChanged} />
</div>
);
}
但是当我从 更新状态时socket.socket.on("chatMessage"
,我得到一个错误
无法对未安装的组件执行 React 状态更新
并且套接字告诉我响应需要很长时间,并且开始发生一些递归。
我应该如何从套接字事件更新我的组件状态?
解决方案
您需要在 useEffect 函数中设置套接字侦听器,否则在每次重新渲染时都会创建一个新实例,而旧实例将继续侦听并导致内存溢出和意外状态更新错误。还要清除您的套接字侦听器
function Chat(props) {
const [messages, setMessages] = useState([]);
const inputRef = useRef();
useEffect(() => {
//The socket is a module that exports the actual socket.io socket
const addMessage = (msg) => setMessages(prevMessages => [...prevMessages, msg]);
socket.socket.on("chatMessage", addMessage)
() => {
// turning of socket listner on unmount
socket.off('chatMessage', addMessage);
}
}, [])
const inputChanged = (e) => {
if (e.key === "Enter") {
socket.sendMessage(inputRef.current.value)
.then(() => {
//do something
})
.catch(console.log);
inputRef.current.value = "";
}
};
return (
<div>
{messages.map((msg, i) => <ChatMessage key={i}>{msg}</ChatMessage>)}
<input ref={inputRef} onKeyPress={inputChanged} />
</div>
);
}
// PS 确保你使用回调方法来更新状态
推荐阅读
- php - SQl 根据 ID 匹配从两个表更新到另一个表
- vue.js - 我正在尝试在 Vue.Js 中构建一个 CRUD 应用程序我无法插入用户
- linux - npm install 在 docker 内部的私有存储库中未运行准备钩子
- xaml - Windows UI 库 - 如何调用动态添加的 NavigationView.MenuItems
- javascript - React map 函数:如何一次输出所有嵌套数组的内容?
- android - 在 Android 模拟器上运行 react-native 项目不起作用
- python - 使用python从pdf转换为文本文件后缺少空格
- windows-10 - SNMPv3 - 将自定义 MIB 文件转换为 python MIB 文件
- jquery - Jquery Datatable 根据另一列计算列
- python - 无法使用 selenium python 在网站上使用 google alert 登录