在两个堆栈之间传递参数-React Native



我的应用程序应该有一个带有谷歌的登录屏幕,所以当登录时,它会进入菜单屏幕。

为了在按下后退按钮时不返回登录屏幕,在认证后进入菜单屏幕后。我已经将堆栈分开,一个用于登录,另一个用于其他屏幕

在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"、"ignedIn"、"photoUrl"不通过事实上,当提醒时

Alert.alert('',JSON.stringify(this.props.navigation.state.params))

在菜单屏幕上(第二个堆栈),它是空的

我做错了什么

为什么我的参数没有通过?因为我可能需要另一个抽屉导航

是否有方法为应用程序中的所有屏幕设置全局参数

有没有更好的方法可以避免按下菜单屏幕而无法进入登录屏幕

编辑:

我设法通过设置一个全局参数来解决这个特定的问题:

global.param= result.param;

但是,我仍然需要一个在两个分开的堆栈之间通过的答案

通过创建两个独立的堆栈,您已经在某种程度上分离了params作用域,您要做的是:将使用不同导航作用域的params发送到一个完全不同的导航作用域,该导航作用域实际上完全不知道前一个,尽管它位于一个共同的父级中。

当您从LoginSplashScreen使用this.props.navigation时,您实际上处于AuthStack的沙盒导航范围中,该范围仅限于其自身导航器的路线。现在,当您将两个堆栈绑定到一个导航器中作为SwitchNavigator的Routes时,您正在进入一个父导航器的范围,该范围提供了自己的导航道具,因此,如果您使用了switch导航器的navigation道具,那么您将在AppStack中获得params,但从那以后。

我建议的是以下三种正确的方法:

  1. 使用登录屏幕作为SwitchNavigator的直接路由,从而删除无用的登录堆栈导航器,该导航器正在分离路由

代码应该看起来像:

const Root= createAppContainer(createSwitchNavigator({
LoginSplashScreen: LoginSplashScreen 
AppStack:AppStack
}, {
initialRouteName: 'LoginSplashScreen',
}));
  1. 使用redux将数据存储在一个常见的可访问存储中,并在其他答案中描述的不同组件上使用它,但这不是主要使用redux的原因

  2. 在切换导航器中使用新组件代替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 navigators docs here react Navigator docs 中所述

在你的情况下,我会发送这样的参数:

this.props.navigation.navigate('AppStack', { screen: 'MenuScreen', params: { signedIn: true, name: result.user.name, photoUrl: result.user.photoUrl }, });

希望这对以后的人有所帮助。我已经测试过了,因为我有一个确切的实现。

据我所见,在你的代码中,一切似乎都很好,可能是你在JSON。对它进行字符串化,也许可以尝试分别获取每个参数,即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-nactive-simple-login-extsample-flow-c4874cf91dde。

我个人建议使用存储系统,因为您的整个应用程序都可以访问auth状态,而不是不断将其作为参数发送。

最新更新