如何在用户注销时重置 TabNavigator(从其他屏幕)
How to reset TabNavigator when user logs out (from other screen)
这是我的项目文件层次结构
RootTabNavigator
| AuthStackNavigator // I want to go back to this navigator
| AuthoScreen
| Welcome Screen
| MainTabNavigator // I want to reset MainTabNavigator
| FeedStacknavigator
| Screen A
| OtherStackNavigatorOne
| Screen E
| OtherStackNavigatorTwo
| Screen D
| MenuStackNavigator
| Menuo <-I'm here and want to reset to 'MainTabNavigator'
and go BACK to 'AuthScreen'
| Screen B
| Screen C
问题
用户在 MenuStackNavigator 和 MainTabNavigator 下的 Menuo 屏幕上。
如果用户没有令牌(当用户注销时),用户将返回到授权屏幕。
但同时我想RESET MainTabNavigator。您可以卸载、执行 NavigationActions.init() 或任何您可以执行的操作。我更喜欢 NavigationActions.init()
我只想将 MainTabNavigator 设置为第一次。
代码
如果没有令牌,我会返回到 Auth Screen(这是有效的)
This code if the part of Menuo Screen
componentWillReceiveProps(nextProps) {
if ( nextProps.token == undefined || _.isNil(nextProps.token) ) {
const backAction = NavigationActions.back({
key: null
})
nextProps.navigation.dispatch(backAction);
...
(问题)我们如何重置 MainTabNavigator 包括子 StackNavigators?
MainTabNavigator.js
export default TabNavigator(
{
Feed: {
screen: FeedStacknavigator,
},
OtherOne: {
screen: OtherStackNavigatorOne,
}
...
}, {
navigationOptions: ({navigation}) => ){
header: null,
tabBarIcon: ({focused}) => ...
...
}
可能的解决方案
我也许可以将 MainTabNavigator 从函数更改为 class 并在那里处理重置 TabNavigator。 (我不确定)。
这一次,我需要一个具体的工作示例。我一直在阅读文档并应用到我的应用程序,但我无法解决这个问题。
如有不明之处请告诉我。
更新
const RootTabNavigator = TabNavigator ({
Auth: {
screen: AuthStackNavigator,
},
Welcome: {
screen: WelcomeScreen,
},
Main: {
screen: MainTabNavigator,
},
}, {
navigationOptions: () => ({
...
}
);
export default class RootNavigator extends React.Component {
componentDidMount() {
this._notificationSubscription = this._registerForPushNotifications();
}
您需要的是将导航器初始化为初始状态。您可以使用 NavigationActions.init()
来做到这一点。您可以了解有关导航操作的更多信息 here。
您可以通过创建自定义导航操作来完成此操作,阅读有关它们的更多信息here。
这里有一些代码可以为您做到这一点:
// First get a hold of your navigator
const navigator = ...
// Get the original handler
const defaultGetStateForAction = navigator.router.getStateForAction
// Then hook into the router handler
navigator.router.getStateForAction = (action, state) => {
if (action.type === 'MyCompleteReset') {
// For your custom action, reset it all
return defaultGetStateForAction(NavigationActions.init())
}
// Handle all other actions with the default handler
return defaultGetStateForAction(action, state)
}
为了触发您的自定义导航操作,您必须从您的 React 组件中按如下方式分派它:
this.props.navigation.dispatch({
type: "MyCompleteReset",
index: 0
})
这在大多数情况下应该有效:
componentWillReceiveProps(nextProps) {
if ( nextProps.token == undefined || _.isNil(nextProps.token) ) {
let action = NavigationActions.reset({
index: 0,
key: null,
actions: [
NavigationActions.navigate({routeName: 'Auth'})
]
});
nextProps.navigation.dispatch(action);
}
...
}
或者尝试通过自定义操作增强您的导航器:
const changeAppNavigator = Navigator => {
const router = Navigator.router;
const defaultGetStateForAction = router.getStateForAction;
router.getStateForAction = (action, state) => {
if (state && action.type === "RESET_TO_AUTH") {
let payLoad = {
index: 0,
key: null,
actions: [NavigationActions.navigate({routeName: "AuthStackNavigator"})]
};
return defaultGetStateForAction(NavigationActions.reset(payLoad), state);
// or this might work for you, not sure:
// return defaultGetStateForAction(NavigationActions.init(), state)
}
return defaultGetStateForAction(action, state);
};
return Navigator;
};
const screens = { ... }
RootTabNavigator = changeAppNavigator(TabNavigator(screens, {
initialRouteName: ...,
...
}));
然后在你的 Menuo Screen
中做:
componentWillReceiveProps(nextProps) {
if ( nextProps.token == undefined || _.isNil(nextProps.token) ) {
nextProps.navigation.dispatch({type: "RESET_TO_AUTH"});
...
您可以通过扩展路由器来定义自定义导航逻辑。要完成您在问题的项目文件层次结构中描述的您想要的,您可以在下面执行类似的操作。
MainTabNavigator.js
...
RootTabNavigator.router.getStateForAction = (action, state) => {
if (state && action.type === 'GoToAuthScreen') {
return {
...state,
index: 0,
};
}
return RootTabNavigator.router.getStateForAction(action, state);
};
MainTabNavigator.router.getStateForAction = (action, state) => {
if (state && action.type === 'GoToAuthScreen') {
return {
...state,
index: 0,
};
}
return MainTabNavigator.router.getStateForAction(action, state);
};
MenuStackNavigator.router.getStateForAction = (action, state) => {
if (state && action.type === 'GoToAuthScreen') {
return {
...state,
index: 0,
};
}
return MenuStackNavigator.router.getStateForAction(action, state);
};
在 Menuo 屏幕文件中
componentWillReceiveProps(nextProps) {
if ( nextProps.token == undefined || _.isNil(nextProps.token) ) {
const goToAuthScreen = () => ({
type: 'GoToAuthScreen',
});
nextProps.navigation.dispatch(goToAuthScreen);
...
}
}
这是我的项目文件层次结构
RootTabNavigator
| AuthStackNavigator // I want to go back to this navigator
| AuthoScreen
| Welcome Screen
| MainTabNavigator // I want to reset MainTabNavigator
| FeedStacknavigator
| Screen A
| OtherStackNavigatorOne
| Screen E
| OtherStackNavigatorTwo
| Screen D
| MenuStackNavigator
| Menuo <-I'm here and want to reset to 'MainTabNavigator'
and go BACK to 'AuthScreen'
| Screen B
| Screen C
问题
用户在 MenuStackNavigator 和 MainTabNavigator 下的 Menuo 屏幕上。
如果用户没有令牌(当用户注销时),用户将返回到授权屏幕。
但同时我想RESET MainTabNavigator。您可以卸载、执行 NavigationActions.init() 或任何您可以执行的操作。我更喜欢 NavigationActions.init()
我只想将 MainTabNavigator 设置为第一次。
代码
如果没有令牌,我会返回到 Auth Screen(这是有效的)
This code if the part of Menuo Screen
componentWillReceiveProps(nextProps) {
if ( nextProps.token == undefined || _.isNil(nextProps.token) ) {
const backAction = NavigationActions.back({
key: null
})
nextProps.navigation.dispatch(backAction);
...
(问题)我们如何重置 MainTabNavigator 包括子 StackNavigators?
MainTabNavigator.js
export default TabNavigator(
{
Feed: {
screen: FeedStacknavigator,
},
OtherOne: {
screen: OtherStackNavigatorOne,
}
...
}, {
navigationOptions: ({navigation}) => ){
header: null,
tabBarIcon: ({focused}) => ...
...
}
可能的解决方案
我也许可以将 MainTabNavigator 从函数更改为 class 并在那里处理重置 TabNavigator。 (我不确定)。
这一次,我需要一个具体的工作示例。我一直在阅读文档并应用到我的应用程序,但我无法解决这个问题。
如有不明之处请告诉我。
更新
const RootTabNavigator = TabNavigator ({
Auth: {
screen: AuthStackNavigator,
},
Welcome: {
screen: WelcomeScreen,
},
Main: {
screen: MainTabNavigator,
},
}, {
navigationOptions: () => ({
...
}
);
export default class RootNavigator extends React.Component {
componentDidMount() {
this._notificationSubscription = this._registerForPushNotifications();
}
您需要的是将导航器初始化为初始状态。您可以使用 NavigationActions.init()
来做到这一点。您可以了解有关导航操作的更多信息 here。
您可以通过创建自定义导航操作来完成此操作,阅读有关它们的更多信息here。
这里有一些代码可以为您做到这一点:
// First get a hold of your navigator
const navigator = ...
// Get the original handler
const defaultGetStateForAction = navigator.router.getStateForAction
// Then hook into the router handler
navigator.router.getStateForAction = (action, state) => {
if (action.type === 'MyCompleteReset') {
// For your custom action, reset it all
return defaultGetStateForAction(NavigationActions.init())
}
// Handle all other actions with the default handler
return defaultGetStateForAction(action, state)
}
为了触发您的自定义导航操作,您必须从您的 React 组件中按如下方式分派它:
this.props.navigation.dispatch({
type: "MyCompleteReset",
index: 0
})
这在大多数情况下应该有效:
componentWillReceiveProps(nextProps) {
if ( nextProps.token == undefined || _.isNil(nextProps.token) ) {
let action = NavigationActions.reset({
index: 0,
key: null,
actions: [
NavigationActions.navigate({routeName: 'Auth'})
]
});
nextProps.navigation.dispatch(action);
}
...
}
或者尝试通过自定义操作增强您的导航器:
const changeAppNavigator = Navigator => {
const router = Navigator.router;
const defaultGetStateForAction = router.getStateForAction;
router.getStateForAction = (action, state) => {
if (state && action.type === "RESET_TO_AUTH") {
let payLoad = {
index: 0,
key: null,
actions: [NavigationActions.navigate({routeName: "AuthStackNavigator"})]
};
return defaultGetStateForAction(NavigationActions.reset(payLoad), state);
// or this might work for you, not sure:
// return defaultGetStateForAction(NavigationActions.init(), state)
}
return defaultGetStateForAction(action, state);
};
return Navigator;
};
const screens = { ... }
RootTabNavigator = changeAppNavigator(TabNavigator(screens, {
initialRouteName: ...,
...
}));
然后在你的 Menuo Screen
中做:
componentWillReceiveProps(nextProps) {
if ( nextProps.token == undefined || _.isNil(nextProps.token) ) {
nextProps.navigation.dispatch({type: "RESET_TO_AUTH"});
...
您可以通过扩展路由器来定义自定义导航逻辑。要完成您在问题的项目文件层次结构中描述的您想要的,您可以在下面执行类似的操作。
MainTabNavigator.js
...
RootTabNavigator.router.getStateForAction = (action, state) => {
if (state && action.type === 'GoToAuthScreen') {
return {
...state,
index: 0,
};
}
return RootTabNavigator.router.getStateForAction(action, state);
};
MainTabNavigator.router.getStateForAction = (action, state) => {
if (state && action.type === 'GoToAuthScreen') {
return {
...state,
index: 0,
};
}
return MainTabNavigator.router.getStateForAction(action, state);
};
MenuStackNavigator.router.getStateForAction = (action, state) => {
if (state && action.type === 'GoToAuthScreen') {
return {
...state,
index: 0,
};
}
return MenuStackNavigator.router.getStateForAction(action, state);
};
在 Menuo 屏幕文件中
componentWillReceiveProps(nextProps) {
if ( nextProps.token == undefined || _.isNil(nextProps.token) ) {
const goToAuthScreen = () => ({
type: 'GoToAuthScreen',
});
nextProps.navigation.dispatch(goToAuthScreen);
...
}
}