React中如何在ComponentWillUnmount中正确调用Firestore的unsubscribe函数?
解决ComponentWillUnmount中调用unsubscribe时报错的问题
你遇到的问题很明确——你在componentWillUnmount里错误地从props中获取unsubscribe,但实际上你把这个函数存在了组件的state里,所以拿到的是undefined,调用undefined()自然会抛出Uncaught TypeError: unsubscribe is not a function的错误。
下面是具体的修正方案:
1. 修正ComponentWillUnmount的逻辑
把从props获取改成从state获取,并且增加类型检查(防止组件卸载时unsubscribe还没存入state的情况):
componentWillUnmount(){ const { unsubscribe } = this.state; // 先判断是否是函数再调用,避免不必要的报错 if (typeof unsubscribe === 'function') { unsubscribe(); } }
2. 优化getNotes方法的写法
你的getNotes里用了that = this来绑定上下文,其实因为用了箭头函数,直接用this就行,同时可以用map简化数组生成的逻辑:
getNotes = () => { const db = this.props.firestore; const colRef = db.collection("users").doc(this.props.uid) .collection("notes"); // 保存监听取消函数到变量 const unsubscribe = colRef.orderBy("timestamp", "asc") .onSnapshot((querySnapshot) => { // 用map替代forEach+push,更简洁高效 const notes = querySnapshot.docs.map(doc => ({ id: doc.id, body: doc.data().body })); this.setState({ notes }); }); // 将unsubscribe存入state this.setState({ unsubscribe }); }
为什么原来的代码会报错?
你在componentWillUnmount中写了var unsubscribe = this.props.unsubscribe;,但你的组件props里并没有传递unsubscribe这个属性,而你实际是在getNotes里把unsubscribe存入了组件自己的state中,所以这里拿到的unsubscribe是undefined,调用一个非函数的值就会触发类型错误。
另外补充一个小细节:setState是异步操作,但在这个场景下,因为componentDidMount在组件挂载后只执行一次,getNotes里的unsubscribe会被正确存入state,后续组件卸载时就能获取到这个函数了。
内容的提问来源于stack exchange,提问作者ViktorMS
相关产品推荐
相关产品推荐

