reactjs - 反应状态没有用 socket.io 更新
问题描述
第一次加载页面时,我需要获取所有信息,这就是为什么我要调用 fetch 请求并将结果设置为 State [singleCall function 做这项工作]除此之外,我正在使用 socket.io 连接 websocket 并监听两个事件(odds_insert_one_two,odds_update_one_two),当我收到通知事件时,我必须检查以前的状态并修改一些内容并更新状态,而无需再次调用获取请求。但是之前的状态仍然是[](初始)。如何获得更新的状态?
片段
const [leagues, setLeagues] = useState([]);
const singleCall = (page = 1, params=null) => {
let path = `${apiPath.getLeaguesMatches}`;
Helper.getData({path, page, params, session}).then(response => {
if(response) {
setLeagues(response.results);
} else {
toast("Something went wrong, please try again");
}
}).catch(err => {
console.log(err);
})
};
const updateData = (record) => {
for(const data of record) {
var {matchId, pivotType, rateOver, rateUnder, rateEqual} = data;
const old_leagues = [...leagues]; // [] becuase of initial state value, that is not updated
const obj_index = old_leagues.findIndex(x => x.match_id == matchId);
if(obj_index > -1) {
old_leagues[obj_index] = { ...old_leagues[obj_index], pivotType, rateOver: rateOver, rateUnder:rateUnder, rateEqual:rateEqual};
setLeagues(old_leagues);
}
}
}
useEffect(() => {
singleCall();
var socket = io.connect('http://localhost:3001', {transports: ['websocket']});
socket.on('connect', () => {
console.log('socket connected:', socket.connected);
});
socket.on('odds_insert_one_two', function (record) {
updateData(record);
});
socket.on('odds_update_one_two', function (record) {
updateData(record);
});
socket.emit('get_odds_one_two');
socket.on('disconnect', function () {
console.log('socket disconnected, reconnecting...');
socket.emit('get_odds_one_two');
});
return () => {
console.log('websocket unmounting!!!!!');
socket.off();
socket.disconnect();
};
}, []);
解决方案
钩子是用一个空的依赖数组创建的useEffect
,因此它只在初始化阶段被调用一次。因此,如果league
state 被更新,它的值将永远不会在updateData()
func 中可见。
您可以做的是将league
值分配给 a ref
,并创建一个新的hook
,每次都会更新。
const leaguesRef = React.useRef(leagues);
React.useEffect(() => {
leaguesRef.current = leagues;
});
leagues
改为更新leaguesRef.current
。
const updateData = (record) => {
for(const data of record) {
var {matchId, pivotType, rateOver, rateUnder, rateEqual} = data;
const old_leagues = [...leaguesRef.current]; // [] becuase of initial state value, that is not updated
const obj_index = old_leagues.findIndex(x => x.match_id == matchId);
if(obj_index > -1) {
old_leagues[obj_index] = { ...old_leagues[obj_index], pivotType, rateOver:
rateOver, rateUnder:rateUnder, rateEqual:rateEqual};
setLeagues(old_leagues);
}
}
}
推荐阅读
- winapi - Win32 API 从提升的程序中恢复原始用户名
- python - n-Tree 打印特定路径:AttributeError: 'list' object has no attribute 'data'
- python - NameError:名称“成员”未定义
- javascript - Javascript - 使用 levenshtein 算法获取多个字符串数组之间的相似度百分比
- laravel - 从不同的文件夹Vue js导入组件
- haskell - “liftM”这个名字的灵感来自数学中的电梯吗?
- python - Python中的分组相关常量
- android - Android复选框如何删除左填充
- python - 制作列表功能时出现动态数组类型错误
- facebook - 用于更新回调 URL 并验证 facebook 应用程序令牌的 API