如何在另一个屏幕中删除监听器 - React Native

How to remove listener in another screen - React Native

我想在离开屏幕前提醒用户 (NewNews.js)。它工作正常,但我不希望在他单击保存按钮 (PreviewSave.js) 时调用它。不再维护移除侦听器。

按下保存按钮后,customAlert 被触发。我想删除 save 函数 (PreviewSave.js) 中的侦听器,但它不起作用。

NewNews.js

let exitListener;

useEffect(() => {
    exitListener = navigation.addListener('beforeRemove', e => {
        e.preventDefault();
        customAlert(                 // <- alerting user and waiting for his response
            string.exit,
            string.exitMore,

            () => {
                navigation.dispatch(e.data.action);
            },
            () => {
                console.log('Cancel Pressed');
            },
            string.understand,
        );

    return () => exitListener()
    },[]);

const renderScene = (...) => {
    ...
    return (
        <PreviewSave ...
            navigation={navigation}
            listener={exitListener}.        // here I try to pass the listener
        />
    );
}

return (
    ...
    <TavView ...
        renderScene={renderScene} ... />
);

PreviewSave.js

...
const save = async () => {
    // listener()
    // listener.remove();
    listener;                              // none of these work

    if (route?.item) {
        navigation.goBack();
        navigation.navigate(string.articles, {
            screen: string.article
        });
    } else {
        navigation.goBack();
    }
};

return (
    ...
    <TouchableOpacity onPress={() => save()}>
         <Text>{string.save}</Text>
    </TouchableOpacity>

);

依赖关系

    "react": "^17.0.2",
    "react-native": "^0.67.4",
    "@react-navigation/bottom-tabs": "^6.0.9",
    "@react-navigation/drawer": "^6.1.8",
    "@react-navigation/native": "^6.0.6",
    "@react-navigation/stack": "^6.0.11"

实际上,您的变量将在下一次渲染批处理时被重置,移除侦听器的功能将丢失。要在后续渲染中保留该功能,您需要使用 useRef

let exitListener = useRef();

useEffect(() => {
    exitListener.current = navigation.addListener('beforeRemove', e => {
        e.preventDefault();
        customAlert(                 // <- alerting user and waiting for his response
            string.exit,
            string.exitMore,

            () => {
                navigation.dispatch(e.data.action);
            },
            () => {
                console.log('Cancel Pressed');
            },
            string.understand,
        );

    return exitListener;
    // return () => exitListener()
    });

然后传过去

const renderScene = (...) => {
    ...
    return (
        <PreviewSave ...
            navigation={navigation}
            listener={exitListener.current}
        />
    );
}