diff --git a/static/examples/5.x/prevent-going-back.js b/static/examples/5.x/prevent-going-back.js index 6e0ddd3659..17fdb414f4 100644 --- a/static/examples/5.x/prevent-going-back.js +++ b/static/examples/5.x/prevent-going-back.js @@ -9,31 +9,33 @@ const EditTextScreen = ({ navigation }) => { const hasUnsavedChanges = Boolean(text); - React.useEffect( - () => - navigation.addListener('beforeRemove', (e) => { - const action = e.data.action; - if (!hasUnsavedChanges) { - return; - } + React.useEffect(() => { + const unsubscribe = navigation.addListener('beforeRemove', (e) => { + const action = e.data.action; + if (!hasUnsavedChanges) { + return; + } - e.preventDefault(); + e.preventDefault(); - Alert.alert( - 'Discard changes?', - 'You have unsaved changes. Are you sure to discard them and leave the screen?', - [ - { text: "Don't leave", style: 'cancel', onPress: () => {} }, - { - text: 'Discard', - style: 'destructive', - onPress: () => navigation.dispatch(action), - }, - ] - ); - }), - [hasUnsavedChanges, navigation] - ); + Alert.alert( + 'Discard changes?', + 'You have unsaved changes. Are you sure to discard them and leave the screen?', + [ + { text: "Don't leave", style: 'cancel', onPress: () => {} }, + { + text: 'Discard', + style: 'destructive', + onPress: () => navigation.dispatch(action), + }, + ] + ); + }); + + return () => { + unsubscribe(); + }; + }, [hasUnsavedChanges, navigation]); return ( diff --git a/static/examples/6.x/prevent-going-back.js b/static/examples/6.x/prevent-going-back.js index 6e0ddd3659..17fdb414f4 100644 --- a/static/examples/6.x/prevent-going-back.js +++ b/static/examples/6.x/prevent-going-back.js @@ -9,31 +9,33 @@ const EditTextScreen = ({ navigation }) => { const hasUnsavedChanges = Boolean(text); - React.useEffect( - () => - navigation.addListener('beforeRemove', (e) => { - const action = e.data.action; - if (!hasUnsavedChanges) { - return; - } + React.useEffect(() => { + const unsubscribe = navigation.addListener('beforeRemove', (e) => { + const action = e.data.action; + if (!hasUnsavedChanges) { + return; + } - e.preventDefault(); + e.preventDefault(); - Alert.alert( - 'Discard changes?', - 'You have unsaved changes. Are you sure to discard them and leave the screen?', - [ - { text: "Don't leave", style: 'cancel', onPress: () => {} }, - { - text: 'Discard', - style: 'destructive', - onPress: () => navigation.dispatch(action), - }, - ] - ); - }), - [hasUnsavedChanges, navigation] - ); + Alert.alert( + 'Discard changes?', + 'You have unsaved changes. Are you sure to discard them and leave the screen?', + [ + { text: "Don't leave", style: 'cancel', onPress: () => {} }, + { + text: 'Discard', + style: 'destructive', + onPress: () => navigation.dispatch(action), + }, + ] + ); + }); + + return () => { + unsubscribe(); + }; + }, [hasUnsavedChanges, navigation]); return ( diff --git a/static/examples/7.x/prevent-going-back.js b/static/examples/7.x/prevent-going-back.js index 6e0ddd3659..17fdb414f4 100644 --- a/static/examples/7.x/prevent-going-back.js +++ b/static/examples/7.x/prevent-going-back.js @@ -9,31 +9,33 @@ const EditTextScreen = ({ navigation }) => { const hasUnsavedChanges = Boolean(text); - React.useEffect( - () => - navigation.addListener('beforeRemove', (e) => { - const action = e.data.action; - if (!hasUnsavedChanges) { - return; - } + React.useEffect(() => { + const unsubscribe = navigation.addListener('beforeRemove', (e) => { + const action = e.data.action; + if (!hasUnsavedChanges) { + return; + } - e.preventDefault(); + e.preventDefault(); - Alert.alert( - 'Discard changes?', - 'You have unsaved changes. Are you sure to discard them and leave the screen?', - [ - { text: "Don't leave", style: 'cancel', onPress: () => {} }, - { - text: 'Discard', - style: 'destructive', - onPress: () => navigation.dispatch(action), - }, - ] - ); - }), - [hasUnsavedChanges, navigation] - ); + Alert.alert( + 'Discard changes?', + 'You have unsaved changes. Are you sure to discard them and leave the screen?', + [ + { text: "Don't leave", style: 'cancel', onPress: () => {} }, + { + text: 'Discard', + style: 'destructive', + onPress: () => navigation.dispatch(action), + }, + ] + ); + }); + + return () => { + unsubscribe(); + }; + }, [hasUnsavedChanges, navigation]); return ( diff --git a/versioned_docs/version-5.x/preventing-going-back.md b/versioned_docs/version-5.x/preventing-going-back.md index 2203fd4574..b7138867f0 100644 --- a/versioned_docs/version-5.x/preventing-going-back.md +++ b/versioned_docs/version-5.x/preventing-going-back.md @@ -28,35 +28,38 @@ function EditText({ navigation }) { const [text, setText] = React.useState(''); const hasUnsavedChanges = Boolean(text); - React.useEffect( - () => - navigation.addListener('beforeRemove', (e) => { - if (!hasUnsavedChanges) { - // If we don't have unsaved changes, then we don't need to do anything - return; - } - - // Prevent default behavior of leaving the screen - e.preventDefault(); - - // Prompt the user before leaving the screen - Alert.alert( - 'Discard changes?', - 'You have unsaved changes. Are you sure to discard them and leave the screen?', - [ - { text: "Don't leave", style: 'cancel', onPress: () => {} }, - { - text: 'Discard', - style: 'destructive', - // If the user confirmed, then we dispatch the action we blocked earlier - // This will continue the action that had triggered the removal of the screen - onPress: () => navigation.dispatch(e.data.action), - }, - ] - ); - }), - [navigation, hasUnsavedChanges] - ); + React.useEffect(() => { + const unsubscribe = navigation.addListener('beforeRemove', (e) => { + if (!hasUnsavedChanges) { + // If we don't have unsaved changes, then we don't need to do anything + return; + } + + // Prevent default behavior of leaving the screen + e.preventDefault(); + + // Prompt the user before leaving the screen + Alert.alert( + 'Discard changes?', + 'You have unsaved changes. Are you sure to discard them and leave the screen?', + [ + { text: "Don't leave", style: 'cancel', onPress: () => {} }, + { + text: 'Discard', + style: 'destructive', + // If the user confirmed, then we dispatch the action we blocked earlier + // This will continue the action that had triggered the removal of the screen + onPress: () => navigation.dispatch(e.data.action), + }, + ] + ); + }); + + // Unsubscribe the listener when the component unmounts to avoid memory leaks + return () => { + unsubscribe(); + }; + }, [navigation, hasUnsavedChanges]); return ( - navigation.addListener('beforeRemove', (e) => { - if (!hasUnsavedChanges) { - // If we don't have unsaved changes, then we don't need to do anything - return; - } - - // Prevent default behavior of leaving the screen - e.preventDefault(); - - // Prompt the user before leaving the screen - Alert.alert( - 'Discard changes?', - 'You have unsaved changes. Are you sure to discard them and leave the screen?', - [ - { text: "Don't leave", style: 'cancel', onPress: () => {} }, - { - text: 'Discard', - style: 'destructive', - // If the user confirmed, then we dispatch the action we blocked earlier - // This will continue the action that had triggered the removal of the screen - onPress: () => navigation.dispatch(e.data.action), - }, - ] - ); - }), - [navigation, hasUnsavedChanges] - ); + React.useEffect(() => { + const unsubscribe = navigation.addListener('beforeRemove', (e) => { + if (!hasUnsavedChanges) { + // If we don't have unsaved changes, then we don't need to do anything + return; + } + + // Prevent default behavior of leaving the screen + e.preventDefault(); + + // Prompt the user before leaving the screen + Alert.alert( + 'Discard changes?', + 'You have unsaved changes. Are you sure to discard them and leave the screen?', + [ + { text: "Don't leave", style: 'cancel', onPress: () => {} }, + { + text: 'Discard', + style: 'destructive', + // If the user confirmed, then we dispatch the action we blocked earlier + // This will continue the action that had triggered the removal of the screen + onPress: () => navigation.dispatch(e.data.action), + }, + ] + ); + }); + + // Unsubscribe the listener when the component unmounts to avoid memory leaks + return () => { + unsubscribe(); + }; + }, [navigation, hasUnsavedChanges]); return ( - navigation.addListener('beforeRemove', (e) => { - if (!hasUnsavedChanges) { - // If we don't have unsaved changes, then we don't need to do anything - return; - } - - // Prevent default behavior of leaving the screen - e.preventDefault(); - - // Prompt the user before leaving the screen - Alert.alert( - 'Discard changes?', - 'You have unsaved changes. Are you sure to discard them and leave the screen?', - [ - { text: "Don't leave", style: 'cancel', onPress: () => {} }, - { - text: 'Discard', - style: 'destructive', - // If the user confirmed, then we dispatch the action we blocked earlier - // This will continue the action that had triggered the removal of the screen - onPress: () => navigation.dispatch(e.data.action), - }, - ] - ); - }), - [navigation, hasUnsavedChanges] - ); + React.useEffect(() => { + const unsubscribe = navigation.addListener('beforeRemove', (e) => { + if (!hasUnsavedChanges) { + // If we don't have unsaved changes, then we don't need to do anything + return; + } + + // Prevent default behavior of leaving the screen + e.preventDefault(); + + // Prompt the user before leaving the screen + Alert.alert( + 'Discard changes?', + 'You have unsaved changes. Are you sure to discard them and leave the screen?', + [ + { text: "Don't leave", style: 'cancel', onPress: () => {} }, + { + text: 'Discard', + style: 'destructive', + // If the user confirmed, then we dispatch the action we blocked earlier + // This will continue the action that had triggered the removal of the screen + onPress: () => navigation.dispatch(e.data.action), + }, + ] + ); + }); + + // Unsubscribe the listener when the component unmounts to avoid memory leaks + return () => { + unsubscribe(); + }; + }, [navigation, hasUnsavedChanges]); return (