我正试图分离此侦听器:
listenForNew() {
const firebase = this.props.firebase;
let newestDate = new Date().getTime();
if(this.state.subitiq.length !== 0) {
newestDate = this.state.subitiq[this.state.subitiq.length-1].date;
}
console.log("listening after date " + (newestDate+1));
const ref = firebase.database().ref().child('subitiq').orderByChild('date').startAt(newestDate+1).on('child_added', snapshot => {
console.log("added new subitie with key " + snapshot.key);
let subitie = snapshot.val();
subitie.key = snapshot.key;
let subitiq = this.state.subitiq.slice(0);
subitiq.push(subitie);
let showedSubitiq = this.state.showedSubitiq.slice(0);
showedSubitiq.push(subitie);
this.setState({subitiq: subitiq, showedSubitiq: showedSubitiq});
//console.log(subitie);
}, error => {
console.error(error);
});
this.addRefListener(ref, 'subitiq', 'child_added');
} // listenForNew()
这是addRefListener():
addRefListener(ref, refPath, listener) {
let refs = this.state.refs;
let listeners = this.state.listeners;
let refPaths = this.state.refPaths;
refs.push(ref);
refPaths.push(refPath);
listeners.push(listener);
this.setState({refPaths: refPaths, refs: refs, listeners: listeners});
} // addRefListener()
这就是我试图分离的方式:
componentWillUnmount() {
this.componentCleanup();
window.removeEventListener('beforeunload', this.componentCleanup); // remove the event handler for normal unmounting
}
componentDidMount() {
window.addEventListener('beforeunload', this.componentCleanup);
//...
}
componentCleanup() { // this will hold the cleanup code
// whatever you want to do when the component is unmounted or page refreshes
const firebase = this.props.firebase;
for(let i=0; i<this.state.refs.length; i++) {
try {
firebase.database().ref().child(this.state.refPaths[i]).off(this.state.listeners[i]);
console.log("removed listener at '" + this.state.refPaths[i] + "' on '" + this.state.listeners[i] + "' #1 block");
} catch(er) {
console.log("error block #1");
console.error(er);
}
try {
firebase.database().ref().child(this.state.refPaths[i]).off(this.state.listeners[i], this.state.refs[i]);
console.log("removed listener at '" + this.state.refPaths[i] + "' on '" + this.state.listeners[i] + "' #2 block");
} catch(er) {
console.log("error block #2");
console.error(er);
}
try {
this.state.refs[i].off(this.state.listeners[i]);
console.log("removed listener at '" + this.state.refPaths[i] + "' on '" + this.state.listeners[i] + "' #3 block");
} catch(er) {
console.log("error block #3");
console.error(er);
}
}
}
我在第3块上出错(this.state.refs [i] .off不是一个函数),第1块和第2块没有给出错误,但实际上它们没有释放。 /> 我发现了很多问题,尝试了很多事情,但我仍然不明白我该怎么做?
答案 0 :(得分:0)
您可以通过将单个监听器作为参数传递给off()来删除它。在不带参数的位置上调用off()会删除该位置上的所有侦听器。
例如,如果您有此侦听器:
const ref = firebase.database().ref().child('subitiq').orderByChild('date').startAt(newestDate+1).on('child_added', snapshot =>
然后将其分离,您需要使用相同的引用并执行以下操作:
ref.off('child_added');
off()
也是Reference
内部的方法
https://firebase.google.com/docs/reference/js/firebase.database.Reference.html#off
答案 1 :(得分:0)
在下一行中,由于具有on(...)
函数,因此您调用的ref
对象不是Reference / Query对象,而是实际上的快照回调函数(snapshot => { /* ... */ }
)。
const ref = firebase.database().ref().child('subitiq').orderByChild('date').startAt(newestDate+1).on('child_added', snapshot => { /* ... */ }, error => { /* ... */ });
要获取引用/查询对象,必须将这些行拆分为以下内容:
let queryRef = firebase.database().ref().child('subitiq').orderByChild('date').startAt(newestDate+1);
let callback = queryRef.on('child_added', snapshot => { /* ... */ }, error => { /* ... */ });
一旦拥有了这两个功能,就可以调用addListenerUnsubscribe
函数的我的版本addRefListener
。
addListenerUnsubscribe(queryRef, 'child_added', callback);
稍后清理组件时,您只需像这样调用unsubscribeAllListeners()
:
componentCleanup() {
unsubscribeAllListeners();
}
addListenerUnsubscribe(ref, eventType, callback, name) {
let listeners = this.state.listeners;
listeners.push({ref: ref, eventType: eventType, cb: callback, name: name});
this.setState({listeners}); // this seems unneccessary
}
unsubscribeAllListeners() {
let listeners = this.state.listeners;
listeners.forEach((listener) => {
listener.ref.off(listener.eventType, listener.callback);
});
this.setState({listeners: []});
}
使用上述代码,如果需要,您还可以按名称删除一组侦听器。
unsubscribeListenersByName(name) {
let listeners = this.state.listeners;
let remaining = listeners.filter((listener) => {
if (name !== listener.name) return true; // keep
listener.ref.off(listener.eventType, listener.callback);
});
// remaining is an array of still active listeners
this.setState({listeners: remaining});
}
参考文献: