提问人:FiFi 提问时间:4/12/2022 最后编辑:FiFi 更新时间:8/17/2022 访问量:1773
为什么 socket.io 事件会从 react 中多次触发?
Why is socket.io event firing multiple times from react?
问:
我有一个连接事件,一旦我登录,我总是到达主屏幕,在主屏幕的 useEffect 上,我有 socket.io 客户端“连接”事件,如下所示。localStorage authToken 是在密码匹配后在登录屏幕上设置的。即使我关闭了 React Strict Mode,我也看到 connect 事件多次触发。
问题似乎出在客户端,因为第二个 useEffect 上的控制台 .log 多次触发。 我应该如何设置 socket.io,使其仅在 HomeScreen 渲染后触发一次?
useEffect(() => {
if(localStorage.getItem('authToken') && !localStorage.getItem('showedLoginStatus')){
toast.success("Login successful!");
localStorage.setItem('showedLoginStatus', 'showed');
}
setSocket(io.connect(backendLink));
}, [])
useEffect(() => {
console.log(socket, localStorage.getItem('authToken'));
socket?.emit("newUser", localStorage.getItem('authToken'));
}, [socket, localStorage.getItem('authToken')])
后端 socket.io 代码如下:
socket.on("newUser", async (jwtToken) => {
const user = await findUserFromJWT(jwtToken);
addNewUser(user._id, socket.id);
console.log('connect print'); printUsers();
})
仅 1 次登录后服务器端的控制台 .log:
connect print
{
userID: new ObjectId("6243ff45c46997fa04ea6e29"),
socketID: '_-9y81H4P7PaUt19AAAB'
}
{
userID: new ObjectId("6243ff45c46997fa04ea6e29"),
socketID: 'cjU_JmCqUOMF619PAAAH'
}
答:
0赞
arfi720
4/12/2022
#1
不完全确定,但是,看看这个答案,似乎将 localStorage 放在 useEffect 依赖项中并不是最好的主意。
不过,为了解决双重调用,根据我的经验,最好使用状态来跟踪 newUser 调用是否完成:
const [newUserRegistered, setNewUserRegistered] = useState(false);
useEffect(() => {
const setNewUser = () => {
if(window.localStorage('newUser') && socket && !newUserRegistered){
//do your socket thing, then
setNewUserRegistered(true);
}
}
window.addEventListener('storage', setNewUser);
return() => {
window.removeEventListener('storage', setNewUser)
}
}, [socket, newUserRegistered])
-1赞
Selcukusu
8/17/2022
#2
尝试删除
<React.StrictMode>
//your code
</React.StrictMode>
index.js 中的标签
评论
socket.emit()
if(!!socket){}