Javascript 处理导航以提醒未保存的更改
我正在使用react navigation中的defaultGetStateForAction截取我的导航,这样我就可以提醒我的用户有未保存的数据,并给他继续导航和删除未保存数据或先保存数据的选项。该数据存储在更高的组件状态中,可通过screenProps提供的功能访问该状态 所以。。。这是我的密码:Javascript 处理导航以提醒未保存的更改,javascript,react-native,react-navigation,expo,react-navigation-stack,Javascript,React Native,React Navigation,Expo,React Navigation Stack,我正在使用react navigation中的defaultGetStateForAction截取我的导航,这样我就可以提醒我的用户有未保存的数据,并给他继续导航和删除未保存数据或先保存数据的选项。该数据存储在更高的组件状态中,可通过screenProps提供的功能访问该状态 所以。。。这是我的密码: const CreateAnimalStack = createStackNavigator({ CreateAnimal: { screen: createAnimalScreen },
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;
我认为这里的主要问题是,
警报
没有阻塞,因此导航仍会发生在警报后面
也就是说,从中,您应该在if
语句中返回null
:它将取消导航
if (...) {
Alert.alert(
'Alert Title',
'My Alert Msg',
// ...
);
return null;
}
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()} />
}
}
然后在Alert OK按钮解析中,您必须重新调度导航操作(而不是返回状态),但问题是您没有可用的dispatch
<代码>分派来自AppContainer
。一种方法是创建一个存储导航器的NavigationService
,如,然后从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);
}
},
在我看来,所有这些代码都很脆弱,非常丑陋
我建议您首先探索一种完全不同的方法,例如,使用自定义onPress回调将默认的headerLeft
组件替换为screennavigationOptions
,而不是监听状态更改
下面是一个简单的未经测试的示例,它从react navigation导入默认的左按钮
if (...) {
Alert.alert(
'Alert Title',
'My Alert Msg',
// ...
);
return null;
}
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()} />
}
}
从“反应导航”导入{HeaderBackButton};
类YourScreen扩展组件{
静态导航选项=({navigation})=>{
const onBack={
警惕,警惕(
“警报标题”,
“我的提醒信息”,
[
{text:'Ask me later',onPress:()=>console.log('Ask me later pressed')},
{
文本:“取消”,
样式:“取消”,
},
{
文本:“确定”,按:()=>{
navigation.goBack();
}
},
],
{可取消:false}
);
}
返回{
headerLeft:onBack()}/>
}
}
我认为这里的主要问题是警报
没有阻塞,因此导航仍会在警报后进行
也就是说,从中,您应该在if
语句中返回null
:它将取消导航
if (...) {
Alert.alert(
'Alert Title',
'My Alert Msg',
// ...
);
return null;
}
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()} />
}
}
然后在Alert OK按钮解析中,您必须重新调度导航操作(而不是返回状态),但问题是您没有可用的dispatch
<代码>分派来自AppContainer
。一种方法是创建一个存储导航器的NavigationService
,如,然后从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);
}
},
在我看来,所有这些代码都很脆弱,非常丑陋
我建议您首先探索一种完全不同的方法,例如,使用自定义onPress回调将默认的headerLeft
组件替换为screennavigationOptions
,而不是监听状态更改
下面是一个简单的未经测试的示例,它从react navigation导入默认的左按钮
if (...) {
Alert.alert(
'Alert Title',
'My Alert Msg',
// ...
);
return null;
}
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()} />
}
}
从“反应导航”导入{HeaderBackButton};
类YourScreen扩展组件{
静态导航选项=({navigation})=>{
const onBack={
警惕,警惕(
“警报标题”,
“我的提醒信息”,
[
{text:'Ask me later',onPress:()=>console.log('Ask me later pressed')},
{
文本:“取消”,
样式:“取消”,
},
{
文本:“确定”,按:()=>{
navigation.goBack();
}
},
],
{可取消:false}
);
}
返回{
headerLeft:onBack()}/>
}
}