You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

RxJS Subject订阅内调用setState触发React内存泄漏报错排查

问题原因
  • 你声明的testSubject是全局的Subject实例,配套的setInterval会每2秒触发一次next推送新值,不会随页面卸载自动终止
  • 你在useFocusEffect中调用了testSubject.subscribe,但没有在返回的清理函数中取消这个订阅:页面第一次离开TestPage时组件已经卸载,但之前绑定的订阅回调仍然存活,当Subject推送新值时,回调里的setData就会触发「已卸载组件更新状态」的警告
  • 第二次进入页面时会新增一个订阅,此时内存里同时存在两个订阅回调:旧回调对应已经卸载的组件实例,新回调对应新挂载的实例,旧回调触发时就会抛出你遇到的警告
修复方案

订阅会返回一个Subscription对象,调用它的unsubscribe方法即可取消当前订阅,将清理逻辑替换为取消订阅即可解决问题,修复后代码如下:

export const testSubject = new Subject<any>();
setInterval(() => {
    testSubject.next({ dest: 'any', msg: [] });
}, 2000);

function TestPage({ route, navigation }) {
    const [data, setData] = useState<any[]>([]);

    useFocusEffect(
        useCallback(() => {
            // 保存订阅实例
            const subscription = testSubject.subscribe(({ dest, msg }) => {
                setData(msg);
            });
            // 页面失焦/卸载时取消订阅
            return () => subscription.unsubscribe();
        }, []),
    );

    return (
        <View>
            <Text>{JSON.stringify(data)}</Text>
            <Button
                onPress={() => {
                    navigation.navigate('home');
                }}
                title="back"
            />
        </View>
    );
}

export default TestPage;

内容的提问来源于stack exchange,提问作者Plochie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 08:00:03