80 votes

Comment naviguer entre différentes piles imbriquées dans la navigation react

L'objectif

En utilisant la navigation réactive, naviguez d'un écran dans un navigateur à un écran dans un navigateur différent.

Plus de détails

Si j'ai la structure de Navigator suivante :

  • Navigateur parental
    • Nested Navigator 1
      • écran A
      • écran B
    • Navigateur imbriqué 2
      • écran C
      • écran D

Comment puis-je passer de l'écran D du navigateur imbriqué 2 à l'écran A du navigateur imbriqué 1 ? Actuellement, si j'essaie de navigation.navigate à l'écran A à partir de l'écran D, il y aura une erreur qui dira qu'il ne connaît pas d'écran A, seulement des écrans C et D.

Je sais que cette question a été posée sous diverses formes à divers endroits sur ce site ainsi que sur GitHub( https://github.com/react-navigation/react-navigation/issues/983 , https://github.com/react-navigation/react-navigation/issues/335#issuecomment-280686611 ) mais pour quelque chose d'aussi basique, il y a un manque de réponses claires et faire défiler des centaines de commentaires GitHub à la recherche d'une solution n'est pas génial.

Peut-être que cette question peut codifier la façon de faire pour tous ceux qui rencontrent ce problème très commun.

0 votes

Pouvez-vous poster le code de votre pile de navigateurs, et aussi si vous utilisez la navigation redux ou non ?

78voto

Stackia Points 1340

Mise à jour : Pour React Navigation v5, voir La réponse de @mahi-man .


Vous pouvez utiliser le troisième paramètre de navigate pour spécifier des sous-actions.

Par exemple, si vous voulez passer de l'écran D sous le navigateur imbriqué 2, à l'écran A sous le navigateur imbriqué 1 :

this.props.navigation.navigate(
    'NestedNavigator1', 
    {}, 
    NavigationActions.navigate({ 
        routeName: 'screenB' 
    })
)

Vérifiez également : https://reactnavigation.org/docs/nesting-navigators/

0 votes

Comment passer des paramètres avec cette méthode ?

6 votes

Qu'est-ce que 'NestedNavigator1' une référence à ?

3 votes

@niksn try this this.props.navigation.navigate('NestedNavigator1', {}, NavigationActions.navigate({routeName : 'screenB', params : {param1 : 'value1'} }))

18voto

Phil Andrews Points 2090

React Navigation v3 :

Navigation.navigate prend maintenant un objet comme paramètre. Vous définissez le nom de la pile puis vous naviguez vers l'itinéraire dans cette pile comme suit...

navigation.navigate(NavigationActions.navigate({
    routeName: 'YOUR_STACK',
    action: NavigationActions.navigate({ routeName: 'YOUR_STACK-subRoute' })
}))

Où 'YOUR_STACK' est le nom de votre pile lorsque vous la créez...

  YOUR_STACK: createStackNavigator({ subRoute: ... })

0 votes

J'ai juste copié-collé le commentaire de la réponse la plus votée. - Dans le cas de NestedNavigator1, il y a un autre navigateur imbriqué à l'intérieur appelé NestedNavigator1.1, avec ScreenA1 et ScreenB1. Comment cela fonctionnerait-il si nous voulions naviguer vers NestedNavigator1.1, ScreenB1 ? Cela serait-il possible ? J'utilise la version 3

4voto

Helga Sokolova Points 46

Dans React Navigation 3

@ZenVentzi, Voici la réponse pour les navigateurs imbriqués à plusieurs niveaux lorsque Nested Navigator 1 a Nested Navigator 1.1 .

  • Navigateur parental
    • Nested Navigator 1
      • Nested Navigator 1.1
        • écran A
        • écran B
    • Navigateur imbriqué 2
      • écran C
      • écran D

Nous pouvons simplement injecter NavigationActions.navigate() plusieurs fois si nécessaire.

  const subNavigateAction = NavigationActions.navigate({
    routeName: 'NestedNavigator1.1',
    action: NavigationActions.navigate({
      routeName: 'ScreenB',
      params: {},
    }),
  });
  const navigateAction = NavigationActions.navigate({
    routeName: 'NestedNavigator1',
    action: subNavigateAction,
  });
  this.props.navigation.dispatch(navigateAction);

UPDATE Pour React Navigation 5, veuillez consulter la réponse de @mahi-man ci-dessus. https://stackoverflow.com/a/60556168/10898950

1 votes

Où se trouve NavigationActions d'où vient-il ? Je ne peux l'importer de nulle part

2voto

Jason Sebring Points 4309

Liberté totale : singleton avec navigationOptions

Si vous avez une situation où vous avez plusieurs piles et sous-piles de navigation, cela peut être frustrant de savoir comment obtenir une référence à la pile désirée étant donné la façon dont React Navigation est configuré. Si vous pouviez simplement faire référence à une pile particulière à tout moment, ce serait beaucoup plus facile. Voici comment.

  1. Créez un singleton spécifique à la pile que vous voulez référencer n'importe où.

    // drawerNavigator.js . (or stackWhatever.js)
    const nav = {}
    export default {
      setRef: ref => nav.ref = ref,
      getRef: () => nav.ref
    }
  2. Définir la référence sur le navigateur souhaité en utilisant navigatorOptions

    import { createBottomTabNavigator } from 'react-navigation'
    import drawerNavigation from '../drawerNavigator'
    
    const TabNavigation = createBottomTabNavigator(
      {
        // screens listed here
      },
      {
        navigationOptions: ({ navigation }) => {
          // !!! secret sauce set a reference to parent
          drawerNavigation.setRef(navigation)
          return {
            // put navigation options
          }
        }
      }
    )
  3. Vous pouvez maintenant faire référence drawerNavigator n'importe où à l'intérieur ou à l'extérieur

    // screen.js
    import drawerNavigator from '../drawerNavigator'
    
    export default class Screen extends React.Component {
      render() {
        return (
          <View>
            <TouchableHighlight onPress={() => drawerNavigator.getRef().openDrawer()}>
              <Text>Open Drawer</Text>
            </TouchableHighlight>
          </View>
        )
      }
    }

Explication

Dans l'étape 2, un navigateur d'onglet est l'un des écrans d'un navigateur de tiroir. Le Tab Navigator doit fermer le tiroir mais aussi, n'importe où dans votre application, vous pouvez appeler drawerNavigator.getRef().closeDrawer() après l'exécution de cette étape. Vous n'êtes pas limité à avoir un accès direct à props.navigation après cette étape.

0 votes

C'est génial !

1 votes

Cela a fonctionné pour moi, sauf que dans React Navigation 5, vous devez faire <Drawer.Navigator screenOptions={({navigation}) => {[save your reference]; return {}}} />

0voto

HungrySoul Points 701

En travaillant sur un projet react-native, je suis tombé sur la même situation. J'ai essayé de multiples façons de naviguer vers l'écran mais sans succès.

Après de nombreux essais, j'ai essayé de passer l'objet de navigation des parents aux enfants et de faire un appel de fonction de navigation et cela a fonctionné.

Si vous voulez naviguer de l'écran D à l'écran A, suivez ces étapes.

-> Passez les accessoires de navigation du navigateur 2 imbriqué à ses enfants en utilisant screenProps.

export default class Home extends Component {
    static navigationOptions = {
        header:null
    };

    constructor(props) {
        super(props);
        this.state = {
            profileData: this.props.navigation.state.params,
            route_index: '',
        }
    }

    render() {
        return (
            <ParentNavigator screenProps={this.props.navigation} />
        );
    }
}

export const ParentNavigator = StackNavigator({
  // ScreenName : { screen : importedClassname }
  Nested1: { screen: nested1 },
  Nested2: { screen : nestes1 }
});

export const nested1 = StackNavigator({
  ScreenA: { screen: screenA },
  ScreenB: { screen : screenB }
});

export const nested2 = StackNavigator({
  ScreenC: { screen: screenC },
  ScreenD: { screen : screenD }
});

Vous pouvez recevoir la navigation dans les enfants en utilisant

const {navigate} = this.props.screenProps.navigation;

Maintenant, cette fonction navigate() peut être utilisée pour naviguer entre les enfants.

Je reconnais que ce processus est un peu déroutant, mais je n'ai pas trouvé de solution et j'ai dû m'y résoudre car je devais répondre à mes besoins.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X