web-dev-qa-db-ja.com

2つのスタック間でパラメーターを渡す-Reactネイティブ

私のアプリには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))

メニュー画面(2番目のスタック)では、空です

私は何が間違っているのですか?

別のドロワーナビゲーションが必要になる可能性があるため、パラメーターが渡されないのはなぜですか?

アプリケーションのすべての画面にグローバルパラメータを設定する方法はありますか?

メニュー画面を押し戻してログイン画面が表示されないようにするためのより良い方法はありますか?

編集:

グローバルパラメータを次のように設定することで、この特定の問題を解決することができました。

global.param= result.param;

しかし、2つの別々のスタック間を通過するための答えがまだ必要です

5
Dor Lugasi-Gal

2つの別々のスタックを作成することで、paramsスコープを切り離しました。これから実行しようとしているのは、異なるナビゲーションスコープを使用してparamsを完全に異なるナビゲーションスコープに送信することです。親。

LoginSplashScreenからthis.props.navigationを使用している場合、実際には、独自のナビゲーターのルートに限定されたAuthStackのサンドボックス化されたナビゲーションスコープ内にいます。これで、SwitchNavigatorのRoutesとして両方のスタックを単一のナビゲーターにバインドする場合、独自のナビゲーションプロップを提供する親ナビゲーターのスコープに入力することになります。したがって、スイッチナビゲーターのnavigationプロップを使用した場合は、 AppStackにパラメータが含まれているはずですが、それ以降です。

私が提案するのは、それを正しく行うための以下の3つの方法です。

  1. ログイン画面をSwitchNavigatorの直接ルートとして使用することにより、ルーティングを切り離しているログイン用の不要なスタックナビゲーターを削除します。

コードは次のようになります。

const Root= createAppContainer(createSwitchNavigator({
   LoginSplashScreen: LoginSplashScreen 
   AppStack:AppStack
}, {
initialRouteName: 'LoginSplashScreen',
}));
  1. reduxを使用して一般的にアクセス可能なストアにデータを保存し、他の回答で説明されているようにさまざまなコンポーネントでデータを使用しますが、これは主にreduxを使用する理由ではありません。

  2. SwitchNavigatorの直接ルートの1つとしてLoginSplashScreenを使用し、新しいコンポーネント内にAppStackをレンダリングし、受信したparamsscreenPropsAppStackとして渡すときに、スイッチナビゲーターでAppStackの代わりに新しいコンポーネントを使用し、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} />
     )
   }
}
4
Suraj Malviya

私があなたのコードで見る限り、すべてがうまくいくようです、それはあなたがそれを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状態にアクセスできるため、個人的にはストレージシステムをお勧めします。

0
Faisal