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

setState causing memory leak inside subject subscribe

我在第二次导航到 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 在 observable subscribe 中不起作用?

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();
            }
        }, []),
    );

这应该有效。