Javascript Firebase取消订阅onSnapshot不起作用
因此,我尝试加载多个元素(RoomItem),每个RoomItem都有一个onSnapshot侦听器,用于侦听实时更改。现在,当我更改我的工作区,加载一组新的RoomItems时,以前的侦听器不会取消订阅,如果该RoomItem中有任何更新,则react会呈现该列表,而不是来自currentWorkspace的该列表Javascript Firebase取消订阅onSnapshot不起作用,javascript,reactjs,firebase,redux,google-cloud-firestore,Javascript,Reactjs,Firebase,Redux,Google Cloud Firestore,因此,我尝试加载多个元素(RoomItem),每个RoomItem都有一个onSnapshot侦听器,用于侦听实时更改。现在,当我更改我的工作区,加载一组新的RoomItems时,以前的侦听器不会取消订阅,如果该RoomItem中有任何更新,则react会呈现该列表,而不是来自currentWorkspace的该列表 const [roomLiveStatus, setRoomLiveStatus] = useState(false); const [unsubscribe, setUn
const [roomLiveStatus, setRoomLiveStatus] = useState(false);
const [unsubscribe, setUnsubscribe] = useState(null);
const getRoomData = (currentWorkspace) => {
const {
roomData,
workspace,
allChannels,
setChannels,
index,
currentUser,
} = props;
const { workspaceId } = workspace;
const workspaceIdLowerCase = workspaceId.toLowerCase();
const { roomId } = roomData;
const roomIdLowerCase = roomId.toLowerCase();
const now = new Date().valueOf();
const query = firebase
.firestore()
.collection(`workspaces/${currentWorkspace.workspaceId}/rooms/${roomId}/messages`);
let unsub;
unsub = query.onSnapshot(
{
includeMetadataChanges: true,
},
function (doc) {
doc.docChanges().forEach((change) => {
if (change.type === "added") {
if (change.doc.data().timestamp >= now) {
console.log("message added ", change.doc.data());
let prevAllChannels = allChannels;
firebase
.firestore()
.collection(`workspaces/${currentWorkspace.workspaceId}/rooms/`)
.doc(`${roomId}`)
.get()
.then((doc) => {
if (doc.exists) {
console.log("updated room data", {
...doc.data(),
roomId: doc.id,
});
prevAllChannels.splice(index, 1, {
...doc.data(),
roomId: doc.id,
lastMessage: change.doc.data(),
});
if(currentWorkspace?.workspaceId === workspaceId) {
switchSort(prevAllChannels);
}
}
});
}
}
if (change.type === "modified") {
console.log("message modified: ", change.doc.data());
let prevAllChannels = allChannels;
firebase
.firestore()
.collection(`workspaces/${workspaceId}/rooms/`)
.doc(`${roomId}`)
.get()
.then((doc) => {
if (doc.exists) {
prevAllChannels.splice(index, 1, {
...doc.data(),
roomId: doc.id,
});
// console.log(prevAllChannels,"prevallchannels",prevSortType,"prevsorttype", props.sortType,"currentsorttype")
if(currentWorkspace?.workspaceId === workspaceId) {
switchSort(prevAllChannels, props.sortType);
}
}
});
}
if (change.type === "removed") {
console.log("message removed: ", change.doc.data());
}
});
}
);
setUnsubscribe(() => unsub);
}
useEffect(() => {
getRoomData(props.currentWorkspace);
}, []);
useEffect(() => {
getRoomData(props.currentWorkspace);
}, [props.sortType, props.currentWorkspace]);
const usePrevious = (value) => {
const ref = useRef();
useEffect(() => {
ref.current = value;
});
return ref.current;
}
const prevCurrentWorkspace = usePrevious(props.currentWorkspace)
useEffect(() => {
if(unsubscribe) {
unsubscribe();
setUnsubscribe(null);
}
},[props.workspace, props.currentWorkspace])
useEffect(() => {
return(() => {
if(unsubscribe)
unsubscribe()
setUnsubscribe(null);
})
},[])
你只需复制粘贴的所有内容你能改进你的代码并只留下相关部分吗,比如删除注释和控制台日志以及与你的问题无关的所有内容,另外,我认为您需要创建一个实例来引用它并关闭它的侦听器,但我无法理解所有这些问题的原因clutter@AKC更新了代码。我已经在状态中设置从onSnapshot返回的unsub方法。后来又叫它取消订阅。这不是实例的一种形式吗?将所有内容都放在useEffect本身中。