【问题标题】:Handle navigation to alert unsaved changes处理导航以提醒未保存的更改
【发布时间】:2019-11-23 01:49:53
【问题描述】:

我正在使用 react-navigation 中的 defaultGetStateForAction 来拦截我的导航,因此我可以提醒我的用户有未保存的数据,并让他选择继续导航并删除未保存的数据或先保存它。这些数据存储在更高的组件状态中,可以通过 screenProps 可用的函数访问该状态

所以...这是我的代码:

const CreateAnimalStack = createStackNavigator({
    CreateAnimal: { screen: createAnimalScreen },
    ListAnimals: { screen: listAnimalsScreen },
    DetailAnimal: { screen: detailAnimalScreen },
    ReviewAnimal: { screen: reviewAnimalScreen },
    ListMarks: { screen: listMarksScreen },
    CreateMark: { screen: createMarkScreen },
}, {
        initialRouteName: 'CreateAnimal',
    });

const defaultGetStateForAction = CreateAnimalStack.router.getStateForAction;

CreateAnimalStack.router.getStateForAction = (action, state) => {
    if (
        state &&
        action.type === NavigationActions.BACK &&
        state.routeName === 'CreateAnimal' &&
        state.routes[state.index].routeName === 'ReviewAnimal' &&
        state.index === 1
    ) {
        Alert.alert(
            'Alert Title',
            'My Alert Msg',
            [
                { text: 'Ask me later', onPress: () => console.log('Ask me later pressed') },
                {
                    text: 'Cancel',
                    onPress: () => {
                        return null;
                    },
                    style: 'cancel',
                },
                {
                    text: 'OK', onPress: () => {
                        const routes = [
                            { routeName: 'CreateAnimal' },
                        ];
                        return {
                            ...state,
                            routes,
                            index: 0,
                        };
                    }
                },
            ],
            { cancelable: false },
        );
        return state;

    } 
    return defaultGetStateForAction(action, state);
};

export default CreateAnimalStack;

【问题讨论】:

    标签: javascript react-native react-navigation expo react-navigation-stack


    【解决方案1】:

    我认为这里的主要问题是 Alert 没有阻塞,所以导航仍然会发生在警报后面。

    话虽如此,从react-navigation documentation 你应该在if 语句中返回null:它将取消导航。

    if (...) {
      Alert.alert(
          'Alert Title',
          'My Alert Msg',
          // ...
      );
    
      return null;
    }
    

    然后在 Alert OK 按钮解析中,您必须重新调度导航操作(而不是返回状态),但问题是您没有可用的 dispatchdispatch 来自 AppContainer。一种方法是创建一个NavigationService 来存储导航器,例如described in the doc,然后从dispatch 导出它。

    // ...
    {
        text: 'OK', onPress: () => {
            const action = NavigationActions.navigate({ routeName: 'CreateAnimal', params: {}});
    
            // here you have to call dispatch from the AppContainer navigator (NavigationService ?)
            NavigationService.dispatch(action);
        }
    },
    

    所有这些代码在我看来都是脆弱而丑陋的。

    我建议您应该首先探索一种完全不同的方式,例如将默认的headerLeft 组件替换为屏幕navigationOptions 与自定义的onPress 回调,而不是监听状态变化。

    这是一个简单的、未经测试的示例,它从 react-navigation 导入默认的左按钮。

    import { HeaderBackButton } from 'react-navigation';
    
    class YourScreen extends Component {
      static navigationOptions = ({ navigation }) => {
        const onBack = {
          Alert.alert(
            'Alert Title',
            'My Alert Msg',
            [
                { text: 'Ask me later', onPress: () => console.log('Ask me later pressed') },
                {
                    text: 'Cancel',
                    style: 'cancel',
                },
                {
                    text: 'OK', onPress: () => {
                        navigation.goBack();
                    }
                },
            ],
            { cancelable: false }
          );
        }
    
        return {
          headerLeft: <HeaderBackButton  onPress={() => onBack()} />
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2012-08-04
      • 2013-01-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-24
      • 2021-08-09
      • 2021-10-08
      相关资源
      最近更新 更多