就像在网络浏览器中一样,我们有onBeforeUnload(vs onUnload)来显示警告或警告“有未保存的数据 - 你确定要回去”。
我正在努力做同样的事情。我在react-navigation的文档中找不到任何内容。
我想做一些像这样的真正hacky,但我不知道它是否正确:
import React, { Component } from 'react'
import { StackNavigator } from 'react-navigation'
export default function ConfirmBackStackNavigator(routes, options) {
const StackNav = StackNavigator(routes, options);
return class ConfirmBackStackNavigatorComponent extends Component {
static router = StackNav.router;
render() {
const { state, goBack } = this.props.navigation;
const nav = {
...this.props.navigation,
goBack: () => {
showConfirmDialog()
.then(didConfirm => didConfirm && goBack(state.key))
}
};
return ( <StackNav navigation = {nav} /> );
}
}
}
答案 0 :(得分:1)
在当前屏幕设置上
this.props.navigation.setParams({
needUserConfirmation: true,
});
在您的堆栈中
const defaultGetStateForAction = Stack.router.getStateForAction;
Stack.router.getStateForAction = (action, state) => {
if (state) {
const { routes, index } = state;
const route = get(routes, index);
const needUserConfirmation = get(route.params, 'needUserConfirmation');
if (
needUserConfirmation &&
['Navigation/BACK', 'Navigation/NAVIGATE'].includes(action.type)
) {
Alert.alert('', "there is unsaved data - are you sure you want to go back", [
{
text: 'Close',
onPress: () => {},
},
{
text: 'Confirm',
onPress: () => {
delete route.params.needUserConfirmation;
state.routes.splice(index, 1, route);
NavigationService.dispatch(action);
},
},
]);
// Returning null from getStateForAction means that the action
// has been handled/blocked, but there is not a new state
return null;
}
}
return defaultGetStateForAction(action, state);
};
注意, 在没有导航道具的情况下进行导航 https://reactnavigation.org/docs/en/navigating-without-navigation-prop.html
NavigationService.js
function dispatch(...args) {
_navigator.dispatch(...args);
}
答案 1 :(得分:1)
反应导航5.7添加了对此的支持:
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}
/>
);
}
答案 2 :(得分:-1)
这可以通过在标题中显示一个自定义后退按钮,并在硬件后退事件导航到导航器之前捕获它来完成。
我们将首先通过覆盖导航选项将页面配置为显示自定义后退按钮:
import React, { Component } from 'react'
import { Button } from 'react-native'
function showConfirmDialog (onConfirmed) { /* ... */ }
class MyPage extends Component {
static navigationOptions ({ navigation }) {
const back = <Button title='Back' onPress={() => showConfirmDialog(() => navigation.goBack())} />
return { headerLeft: back }
}
// ...
}
下一步是覆盖硬件后退按钮。为此,我们将使用软件包react-navigation-backhandler
:
// ...
import { AndroidBackHandler } from 'react-navigation-backhandler'
class MyPage extends Component {
// ...
onHardwareBackButton = () => {
showConfirmDialog(() => this.props.navigation.goBack())
return true
}
render () {
return (
<AndroidBackHandler onBackPress={this.onHardwareBackButton}>
{/* ... */}
</AndroidBackHandler>
)
}
}
答案 3 :(得分:-2)
我真的会改变这种方法,在原生中你没有网络的限制,我从来没有看到过这种模式的实现。其他人所做的是他们保存数据并提供一个链接,以便您在以后离开的地方继续。根据您的应用程序,您可以在不同的地方进行,但我真的会看一下平台的导航模式。