合并Firebase实时监听unsubscribe函数触发栈溢出错误的技术求助
问题分析与修复
问题根源
你遇到的RangeError: Maximum call stack size exceeded是因为在onScrollToBottom里重写unsubscribe函数时触发了无限递归:
unsubscribe = () => { this.state.unsubscribe() unsubscribe() // 此处的unsubscribe就是当前新定义的函数,会无限调用自身 }
另外直接依赖this.state.unsubscribe存在风险,因为setState是异步操作,可能无法获取到最新的状态值。
修复方案
不要每次替换单个unsubscribe函数,而是维护一个数组统一存储所有的unsubscribe函数,便于批量管理:
componentDidMount = async () => { // 初始化存储unsubscribe的数组 this.unsubscribeList = [] const unsubscribe = await getDocsRealtime() this.unsubscribeList.push(unsubscribe) window.addEventListener('scroll', this.onScrollToBottom) } onScrollToBottom = async () => { if (window.scrollY > placeholderTop) { const unsubscribe = await getDocsRealtime() // 将新的unsubscribe加入数组 this.unsubscribeList.push(unsubscribe) } } componentWillUnmount = () => { // 遍历执行所有unsubscribe函数 this.unsubscribeList.forEach(unsubscribe => unsubscribe()) window.removeEventListener('scroll', this.onScrollToBottom) }
额外优化(用state管理)
如果组件内其他逻辑需要依赖该状态,也可以用数组类型的state来维护:
componentDidMount = async () => { const unsubscribe = await getDocsRealtime() this.setState({ unsubscribeList: [unsubscribe] }) window.addEventListener('scroll', this.onScrollToBottom) } onScrollToBottom = async () => { if (window.scrollY > placeholderTop) { const unsubscribe = await getDocsRealtime() this.setState(prevState => ({ unsubscribeList: [...prevState.unsubscribeList, unsubscribe] })) } } componentWillUnmount = () => { this.state.unsubscribeList?.forEach(unsubscribe => unsubscribe()) window.removeEventListener('scroll', this.onScrollToBottom) }
内容的提问来源于stack exchange,提问作者Inaara Kalani
相关产品推荐
相关产品推荐

