套接字侦听器未从 React 状态获取更新
Socket listener not getting updates from React state
我有一个组件,我在其中将我的状态从传递的参数设置到组件
function ChatList({ bookingList, session, setActiveChat, setBookingList, socket }){
const [activeList, setActiveList] = useState(bookingList);
const [defaultList, setDefaultList] = useState(bookingList);
我根据传递的参数设置 activeList 状态,然后在单击时更新状态以显示筛选结果
const changeTab = (index) => {
if(index === 0){
setActiveList(defaultList);
if(defaultList.length > 0){
setActiveChat(defaultList[0]);
}else{
setActiveChat(null);
}
}else {
let result = bookingList.filter(booking => booking.is_service_provider == false);
setActiveList(result);
if(result.length > 0){
setActiveChat(result[0]);
}else{
setActiveChat(null);
}
}
因此最终用户可以根据所选索引过滤他们的聊天列表
一切正常,DOM 已更新,如果我从常规函数调用状态,它会显示正确的状态。
但是当我尝试从套接字侦听器更新状态时,我得到的是原始状态而不是过滤后的状态
useEffect(() => {
socket.on('notification', (payload) => {
let list_index = activeList.findIndex(obj => obj.id === payload.room);
if(list_index > -1){
let copy = [...activeList];
copy[list_index].latest_message = payload.message;
setActiveList(copy);
}else{
//Handle if user isnt in the correct segment
}
});
},[activeList])
这里的问题是 activeList 在过滤后应该只有 2 个元素,但在套接字侦听器中,它获得了 activeList 以及过滤前的所有元素。
我什至用随机的 onclick 侦听器对此进行了测试,onclick 函数获得了正确的状态,那么为什么我的套接字侦听器没有获得更新的状态?
谢谢
每当 activeList
更改时,您都会添加一个侦听器,但不会删除以前的处理程序。它可能会引起你的注意
所以,尝试使用 useEffect
的 return
。
useEffect(() => {
function handler(payload) {....}
socket.on('notification', handler);
return () => socket.off('notification', handler);
}, [activeList]);
此外,当您只想更新 activeList
时,setter 函数会获取以前的值,因此您可以直接使用它,然后您的效果将不需要任何依赖,除了参考 setter 函数。
useEffect(() => {
function handler(payload) {
...
setActiveList((prev) => {
const index = prev.findIndex(obj => obj.id === payload.room);
if (...) return [];
return [];
});
}
socket.on('notification', handler);
return () => socket.off('notification', handler);
}, [setActiveList]);
我有一个组件,我在其中将我的状态从传递的参数设置到组件
function ChatList({ bookingList, session, setActiveChat, setBookingList, socket }){
const [activeList, setActiveList] = useState(bookingList);
const [defaultList, setDefaultList] = useState(bookingList);
我根据传递的参数设置 activeList 状态,然后在单击时更新状态以显示筛选结果
const changeTab = (index) => {
if(index === 0){
setActiveList(defaultList);
if(defaultList.length > 0){
setActiveChat(defaultList[0]);
}else{
setActiveChat(null);
}
}else {
let result = bookingList.filter(booking => booking.is_service_provider == false);
setActiveList(result);
if(result.length > 0){
setActiveChat(result[0]);
}else{
setActiveChat(null);
}
}
因此最终用户可以根据所选索引过滤他们的聊天列表
一切正常,DOM 已更新,如果我从常规函数调用状态,它会显示正确的状态。
但是当我尝试从套接字侦听器更新状态时,我得到的是原始状态而不是过滤后的状态
useEffect(() => {
socket.on('notification', (payload) => {
let list_index = activeList.findIndex(obj => obj.id === payload.room);
if(list_index > -1){
let copy = [...activeList];
copy[list_index].latest_message = payload.message;
setActiveList(copy);
}else{
//Handle if user isnt in the correct segment
}
});
},[activeList])
这里的问题是 activeList 在过滤后应该只有 2 个元素,但在套接字侦听器中,它获得了 activeList 以及过滤前的所有元素。
我什至用随机的 onclick 侦听器对此进行了测试,onclick 函数获得了正确的状态,那么为什么我的套接字侦听器没有获得更新的状态?
谢谢
每当 activeList
更改时,您都会添加一个侦听器,但不会删除以前的处理程序。它可能会引起你的注意
所以,尝试使用 useEffect
的 return
。
useEffect(() => {
function handler(payload) {....}
socket.on('notification', handler);
return () => socket.off('notification', handler);
}, [activeList]);
此外,当您只想更新 activeList
时,setter 函数会获取以前的值,因此您可以直接使用它,然后您的效果将不需要任何依赖,除了参考 setter 函数。
useEffect(() => {
function handler(payload) {
...
setActiveList((prev) => {
const index = prev.findIndex(obj => obj.id === payload.room);
if (...) return [];
return [];
});
}
socket.on('notification', handler);
return () => socket.off('notification', handler);
}, [setActiveList]);