【问题标题】:Intercept back event in an react app to confirm save在反应应用程序中拦截返回事件以确认保存
【发布时间】:2019-06-05 19:58:37
【问题描述】:

我正在使用 expo.io 构建一个反应原生应用程序。

应用正在使用 Stack Navigator 在页面(卡片)之间移动。

我的问题是我有一个页面,用户可以在其中创建新项目,我想在他们离开页面时保存这些项目。 我不想保存他们的所有更改,而是想在离开页面之前提示用户是否要保存更改,以便他们有机会放弃所做的任何更改。

我无法找到退出页面的事件,我可以挂钩并提示用户是否要保存更改? 我发现最接近我想要做的事情是在backhandler,但这仅适用于 Android 后退按钮。

如果用户使用卡片标题中的后退按钮返回,或者他们使用滑动手势,有没有办法做类似的事情?

【问题讨论】:

    标签: reactjs react-native react-navigation expo


    【解决方案1】:

    使用NavigationEvents。向您的组件添加事件侦听器。

    onWillFocus - 事件监听器

    onDidFocus - 事件监听器

    onWillBlur - 事件监听器

    onDidBlur - 事件监听器

    例如,当下一个屏幕聚焦时,以下内容将被触发。在另一个屏幕中,将用户的更改保存在临时存储中,当他们导航回来时,获取那些未保存的更改并提示用户是否要保存或不是。

    focusSubscription = null;
    
    onWillFocus = (payload) => {
    
      if (payload && payload.action && payload.action.type && payload.action.type === 'Navigation/BACK') {
    
        // get values from storage here
        // if there were unsaved changes prompt the user if they want to those changes or not
      }
    };
    
    componentDidMount = () => {
    
      this.focusSubscription = this.props.navigation.addListener(
        'willFocus',
        this.onWillFocus,
      );
     }
    
    componentWillUnmount = () => {
      this.focusSubscription && this.focusSubscription.remove();
      this.focusSubscription = null;
    };
    

    Demo

    【讨论】:

    • 对不起,我忘了补充,我已经查看了挂载和模糊事件,以便在您离开屏幕时始终保存,但我不确定我是否能够弹出模式并暂停在我等待确认用户想要保存时的转换。谢谢,明天我会看看有什么可能
    【解决方案2】:

    React Navigation 在 5.7 版中添加了 beforeRemove 事件,您可以使用它。

    这是他们网站上的演示:

    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]
      );
    
      return (
        <TextInput
          value={text}
          placeholder="Type something…"
          onChangeText={setText}
        />
      );
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-03-25
      • 1970-01-01
      • 2016-05-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多