在两个堆栈之间传递参数 - React Native
pass parameters between two stacks - React Native
我的应用程序应该有一个登录屏幕,Google,所以当登录后它会进入菜单屏幕。
为了在验证后进入菜单屏幕后,按下后退按钮时不返回登录屏幕。
我已经将堆栈分开,一个用于登录,一个用于其他屏幕
在App.js中:
const AuthStack = createStackNavigator({
LoginSplashScreen: LoginSplashScreen
});
const AppStack = createStackNavigator({
MenuScreen:MenuScreen,
DetailsScreen: DetailsScreen,
PhotoScreen: PhotoScreen,
DocumentScreen: DocumentScreen,
AudioScreen: AudioScreen,
ScheduleScreen: ScheduleScreen,
SettingsScreen: SettingsScreen,
FilesScreen: FilesScreen,
GalleryScreen: GalleryScreen
});
const Root= createAppContainer(createSwitchNavigator(
{
AuthStack:AuthStack,
AppStack:AppStack
},
{
initialRouteName: 'AuthStack',
}
));
export default class App extends React.Component {
render() {
return (
<Root/>
)
}
}
因此在 LoginSplashScreen 中
验证后,我使用此代码进行导航:
this.props.navigation.navigate('AppStack', {
signedIn: true,
name: result.user.name,
photoUrl: result.user.photoUrl
});
导航效果很好,但参数 'name'、'signedIn'、'photoUrl'
禁止通过
事实上,当警报
Alert.alert('',JSON.stringify(this.props.navigation.state.params))
在菜单屏幕上(第二个堆栈),它是空的
我做错了什么?
为什么我的参数没有通过?因为我可能需要另一个抽屉导航。
有没有办法为应用程序中的所有屏幕设置全局参数?
是否有更好的方法来避免在菜单屏幕上按回键而无法进入登录屏幕?
编辑:
我设法通过设置全局参数解决了这个特定问题:
global.param= result.param;
但是,我仍然需要一个在 2 个分开的堆栈之间传递的答案
就我在你的代码中看到的,一切似乎都很好,可能是你 JSON.stringifying 它,也许尝试分别获取每个参数,即 this.props.navigation.getParam('signedIn', false);
对于使用 react-navigation
的身份验证流程,您应该遵循本指南:https://reactnavigation.org/docs/en/auth-flow.html,这样您就不会在登录后返回按钮。
为了存储您从 google 返回的身份验证响应等数据,我建议使用 AsyncStorage
或其他形式的存储库,例如 react-redux
。这是一个使用 react-redux
的非常简单的示例:https://medium.com/@aurelie.lebec/redux-and-react-native-simple-login-example-flow-c4874cf91dde.
我个人会推荐一个存储系统,因为您的整个应用程序都可以访问 auth
状态,而不是不断地将其作为参数发送。
通过创建两个单独的堆栈,您已经分离了参数范围,您想要做的是:使用不同的导航范围将参数发送到完全不同的导航范围,实际上完全不知道前一个导航范围虽然生活在一个普通的 parent.
当您使用 LoginSplashScreen
中的 this.props.navigation
时,您实际上处于 AuthStack
的沙盒导航范围内,该范围仅限于其自己的导航器路线。现在,当您将两个堆栈绑定在单个导航器中作为 SwitchNavigator 的 Routes
时,您将进入一个 parent 导航器的范围,它提供自己的导航道具,因此如果您使用 navigation
switch navigator 的 prop,那么你会在你的 AppStack 中获得参数,但是因为。
我建议的是以下三种正确的方法:
- 使用登录屏幕作为 SwitchNavigator 的直接路由,从而删除无用的堆栈导航器以用于分离路由。
代码应如下所示:
const Root= createAppContainer(createSwitchNavigator({
LoginSplashScreen: LoginSplashScreen
AppStack:AppStack
}, {
initialRouteName: 'LoginSplashScreen',
}));
使用 redux 将数据存储在一个通常可访问的存储中,并在其他答案中描述的不同组件上使用它,但这不是主要使用 redux 的原因。
在 Switch 导航器中使用新组件代替 AppStack,同时将 LoginSplashScreen
作为 SwitchNavigator 的直接路由之一并在内部呈现 AppStack
新组件并在 AppStack
中将接收到的 params
作为 screenProps
传递,然后简单地在堆栈路由中使用 screenProps。
代码应如下所示:
const Root= createAppContainer(createSwitchNavigator({
LoginSplashScreen: LoginSplashScreen,
MyMediatorScreen: MyFancyComponent
}, {
initialRouteName: 'AuthStack',
}));
例如。 FancyComponent 将如下所示:
class MyFancyComponent extends React.Component{
constructor (props){
super (props);
}
render () {
const {params} = this.props.navigation.state;
return (
<AppStack screenProps = {params} />
)
}
}
在某些情况下,如果您不想为了关注点分离而分离堆栈,或者像您的情况一样,您可以在这里做的是通过嵌套导航器传递参数,如反应导航器文档中所述 React Navigator Docs
在你的情况下,我会这样发送参数:
this.props.navigation.navigate('AppStack', { screen: 'MenuScreen', params: { signedIn: true, name: result.user.name, photoUrl: result.user.photoUrl }, });
希望这对以后的人有所帮助。我已经对此进行了测试,因为我有一个确切的实现。
我的应用程序应该有一个登录屏幕,Google,所以当登录后它会进入菜单屏幕。
为了在验证后进入菜单屏幕后,按下后退按钮时不返回登录屏幕。 我已经将堆栈分开,一个用于登录,一个用于其他屏幕
在App.js中:
const AuthStack = createStackNavigator({
LoginSplashScreen: LoginSplashScreen
});
const AppStack = createStackNavigator({
MenuScreen:MenuScreen,
DetailsScreen: DetailsScreen,
PhotoScreen: PhotoScreen,
DocumentScreen: DocumentScreen,
AudioScreen: AudioScreen,
ScheduleScreen: ScheduleScreen,
SettingsScreen: SettingsScreen,
FilesScreen: FilesScreen,
GalleryScreen: GalleryScreen
});
const Root= createAppContainer(createSwitchNavigator(
{
AuthStack:AuthStack,
AppStack:AppStack
},
{
initialRouteName: 'AuthStack',
}
));
export default class App extends React.Component {
render() {
return (
<Root/>
)
}
}
因此在 LoginSplashScreen 中 验证后,我使用此代码进行导航:
this.props.navigation.navigate('AppStack', {
signedIn: true,
name: result.user.name,
photoUrl: result.user.photoUrl
});
导航效果很好,但参数 'name'、'signedIn'、'photoUrl' 禁止通过 事实上,当警报
Alert.alert('',JSON.stringify(this.props.navigation.state.params))
在菜单屏幕上(第二个堆栈),它是空的
我做错了什么?
为什么我的参数没有通过?因为我可能需要另一个抽屉导航。
有没有办法为应用程序中的所有屏幕设置全局参数?
是否有更好的方法来避免在菜单屏幕上按回键而无法进入登录屏幕?
编辑:
我设法通过设置全局参数解决了这个特定问题:
global.param= result.param;
但是,我仍然需要一个在 2 个分开的堆栈之间传递的答案
就我在你的代码中看到的,一切似乎都很好,可能是你 JSON.stringifying 它,也许尝试分别获取每个参数,即 this.props.navigation.getParam('signedIn', false);
对于使用 react-navigation
的身份验证流程,您应该遵循本指南:https://reactnavigation.org/docs/en/auth-flow.html,这样您就不会在登录后返回按钮。
为了存储您从 google 返回的身份验证响应等数据,我建议使用 AsyncStorage
或其他形式的存储库,例如 react-redux
。这是一个使用 react-redux
的非常简单的示例:https://medium.com/@aurelie.lebec/redux-and-react-native-simple-login-example-flow-c4874cf91dde.
我个人会推荐一个存储系统,因为您的整个应用程序都可以访问 auth
状态,而不是不断地将其作为参数发送。
通过创建两个单独的堆栈,您已经分离了参数范围,您想要做的是:使用不同的导航范围将参数发送到完全不同的导航范围,实际上完全不知道前一个导航范围虽然生活在一个普通的 parent.
当您使用 LoginSplashScreen
中的 this.props.navigation
时,您实际上处于 AuthStack
的沙盒导航范围内,该范围仅限于其自己的导航器路线。现在,当您将两个堆栈绑定在单个导航器中作为 SwitchNavigator 的 Routes
时,您将进入一个 parent 导航器的范围,它提供自己的导航道具,因此如果您使用 navigation
switch navigator 的 prop,那么你会在你的 AppStack 中获得参数,但是因为。
我建议的是以下三种正确的方法:
- 使用登录屏幕作为 SwitchNavigator 的直接路由,从而删除无用的堆栈导航器以用于分离路由。
代码应如下所示:
const Root= createAppContainer(createSwitchNavigator({
LoginSplashScreen: LoginSplashScreen
AppStack:AppStack
}, {
initialRouteName: 'LoginSplashScreen',
}));
使用 redux 将数据存储在一个通常可访问的存储中,并在其他答案中描述的不同组件上使用它,但这不是主要使用 redux 的原因。
在 Switch 导航器中使用新组件代替 AppStack,同时将
LoginSplashScreen
作为 SwitchNavigator 的直接路由之一并在内部呈现AppStack
新组件并在AppStack
中将接收到的params
作为screenProps
传递,然后简单地在堆栈路由中使用 screenProps。
代码应如下所示:
const Root= createAppContainer(createSwitchNavigator({
LoginSplashScreen: LoginSplashScreen,
MyMediatorScreen: MyFancyComponent
}, {
initialRouteName: 'AuthStack',
}));
例如。 FancyComponent 将如下所示:
class MyFancyComponent extends React.Component{
constructor (props){
super (props);
}
render () {
const {params} = this.props.navigation.state;
return (
<AppStack screenProps = {params} />
)
}
}
在某些情况下,如果您不想为了关注点分离而分离堆栈,或者像您的情况一样,您可以在这里做的是通过嵌套导航器传递参数,如反应导航器文档中所述 React Navigator Docs
在你的情况下,我会这样发送参数:
this.props.navigation.navigate('AppStack', { screen: 'MenuScreen', params: { signedIn: true, name: result.user.name, photoUrl: result.user.photoUrl }, });
希望这对以后的人有所帮助。我已经对此进行了测试,因为我有一个确切的实现。