父组件useEffect异步传递的props在子组件useEffect清理时丢失怎么解决
问题根本原因
- 子组件useEffect的依赖数组为空,受React闭包特性限制,该effect(包括其返回的清理函数)只会捕获组件首次渲染时的
currentChat值。父组件初始状态下currentChat为null,且initiateChat是异步执行逻辑,因此子组件首次挂载时拿到的currentChat就是初始null,且永远不会更新。 - 订阅逻辑写法存在错误:
onSnapshot调用后会直接返回取消订阅的函数,你当前的代码在清理函数中重新调用了一次onSnapshot,既没有取消之前的订阅,父组件卸载时还会用初始的null值调用SDK,直接触发类型错误。
规范解决方案
修正子组件的useEffect逻辑,做三处调整:
- 将
currentChat加入useEffect依赖数组,保证每次currentChat更新时,effect都会使用最新值重建监听 - 增加非空判断,仅当
currentChat有有效值时才创建订阅 - 正确接收
onSnapshot返回的取消订阅函数,清理时直接调用
修正后的代码示例:
const Chat = (props) => { const { currentChat } = props; useEffect(() => { // 无有效chat ID时不创建监听 if (!currentChat) return; // 接收取消订阅函数 const unsubscribe = onSnapshot( collection(database, 'chats', currentChat, 'messages'), (snapshot) => { // 原有消息处理逻辑 }, (error) => { console.log(error); } ); // 清理时直接调用取消订阅 return () => unsubscribe(); }, [currentChat]); // 加入依赖 // 其他组件逻辑 }
效果说明
调整后,当父组件异步更新currentChat为有效值时,子组件effect会自动重建监听,使用最新的chat ID创建订阅。父组件卸载触发清理时,执行的是最新的订阅对应的取消函数,不会再访问初始的null值,类型错误自然消失。
内容的提问来源于stack exchange,提问作者grubsztyl
相关产品推荐
相关产品推荐

