我目前正在使用带有Hooks的React与Hooks一起学习Socket.io,并尝试创建一个计时器,当您按下开始按钮时,计时器将启动,并且每秒钟使用socket.io发送到服务器的时间为
服务器获得正确的时间,我将响应发送回客户端。
问题是当我在客户端console.log该响应时,它多次获得响应示例
这是我的index.js(NODE)
const express = require('express');
const app = express();
const socket = require('socket.io');
server = app.listen(8080, function(){
console.log('Server is running on port 8080')
});
io = socket(server);
io.on('connection', (socket) => {
socket.on('SEND_TIME', function(data){
//here the data object is correct
socket.emit('RECEIVE_MESSAGE', data); //sending back to client
})
});
这是我的React App
App.js
import React from "react";
import io from "socket.io-client";
import { Route, Switch } from "react-router-dom";
import TimerComponent from "./components/Timer";
const App = () => {
const socket = io("localhost:8080");
return (
<React.Fragment>
<Switch>
<Route path="/" exact render={(routeProps)=> <TimerComponent {...routeProps} io={socket} />
} />
</Switch>
</React.Fragment>
);
};
export default App;
计时器组件
import React, { useEffect, useState } from "react";
import { useStopwatch } from "react-timer-hook";
export default function Timer({io}) {
const [isActive, setIsActive] = useState(false);
const { seconds, minutes, hours, start, pause, reset } = useStopwatch({
autoStart: false
});
io.on('RECEIVE_MESSAGE', (data)=>{ //This is printing multiple times
console.log('RECIEVED FROM SERVER',data)
});
useEffect(() => {
if(isActive){
io.emit('SEND_TIME',{
time:`${formatDate(hours)}:${formatDate(minutes)}:${formatDate(seconds)}`
})
}
});
const formatDate = t => (t <=9)?`0${t}`:t;
const handleStart = () => {
setIsActive(!isActive);
if (isActive) {
pause();
} else {
start();
}
};
const handleReset = () => {
reset();
setIsActive(false);
};
return (
<div style={{ textAlign: "center" }}>
<div style={{ fontSize: "100px" }}>
<span>{formatDate(hours)}</span>:<span>{formatDate(minutes)}</span>:
<span>{formatDate(seconds)}</span>
</div>
<button onClick={handleStart}>{isActive ? "Stop" : "Start"}</button>
<button onClick={handleReset}>Reset</button>
</div>
);
}
如果我在app.js上添加事件处理程序(io.on('RECEIVE MESSAGE'))而不是Timer组件,它将正常工作(每秒仅打印一次)
我认为该问题与react useEffect挂钩和渲染行为有关
谢谢!
答案 0 :(得分:0)
使用useEffect()
时,请将[isActive]
数组传递给useEffect()方法的第二个参数。
useEffect(() => {
if(isActive){
io.emit('SEND_TIME',{
time:`${formatDate(hours)}:${formatDate(minutes)}:${formatDate(seconds)}`
})
}
},[isActive]);
页面呈现时,useEffect()也会运行多次。但是,如果您在useEffect()的第二个参数中传递[isActive]
,则useEffect()将跟踪isActive
,如果更改,则仅useEffect()将运行。