setState导致主题订阅内部内存泄漏



我在第二次导航到TestPage时遇到错误。代码是工作良好的第一次导航,但我得到错误的第二次导航。

Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.

我注意到,如果我删除setinterval块,错误不会发生。

来自可观察的数据在Text中反映良好,但我无法理解是什么导致了这个错误。因此,我的问题是为什么setState不能在可观察对象订阅中工作?

export const testSubject = new Subject<any>();
setInterval(() => {
testSubject.next({ dest: 'any', msg: [] });
}, 2000);
function TestPage({ route, navigation }) {
const [data, setData] = useState<any[]>([]);
useFocusEffect(
useCallback(() => {
testSubject.subscribe(({ dest, msg }) => {
setData(msg);
});
return () => _cleanup();
}, []),
);
const _cleanup = () => {};
return (
<View>
<Text>{JSON.stringify(data)}</Text>
<Button
onPress={() => {
navigation.navigate('home');
}}
title="back"
/>
</View>
);
}
export default TestPage;

我不确定useFocusEffect(useCallback(...))到底是什么,但我假设它相当于常规的useEffect

您遇到的问题是,当组件卸载时,您没有清理对流的订阅。当testSubject上有新的更新时,旧的实例(已卸载)将在卸载组件上调用setData(),并且react会报错。

为什么_cleanup函数什么都不做?你只需要完成它:

useFocusEffect(
useCallback(() => {
const subscription = testSubject.subscribe(({ dest, msg }) => {
setData(msg);
});
return () => {
subscription.unsubscribe();
}
}, []),
);

应该可以。

最新更新