reactjs - 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 块不会发生错误。
observable 中的数据反映良好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();
}
}, []),
);
这应该有效。
推荐阅读
- operating-system - 2个以上的音频节目怎么能同时在扬声器上说出来?
- c++ - 迷失在试图理解这个结构编码问题
- jquery - 将表单输入附加到dom后如何专注于表单输入?
- dart - 如何转换地图
到地图 在飞镖? - mongodb - 如何在 mongo 查询中执行嵌套查找?
- python - 将对象正确导入烧瓶?Flask 无法导入姓名邮件
- spring-boot - java.lang.NoSuchMethodError:org.springframework.web.reactive.socket.client.ReactorNettyWebSocketClient。
(Ljava/util/function/Consumer;)V - scala - Kafka:是否有用于 scala 的 Kalfa 客户端 API?
- object - 对象的ES6过滤器数组是否存在属性
- arrays - 如何以编程方式列出 Ruby 中 Array 的所有方法?