web-dev-qa-db-fra.com

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

Le but

À l’aide de la navigation par réaction, naviguez d’un écran d’un navigateur à un autre d’un navigateur.

Plus de détails

Si j'ai la structure de navigateur suivante:

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

comment passer de l'écran D sous le navigateur imbriqué 2 à l'écran A sous le navigateur imbriqué 1? À l'heure actuelle, si j'essaie de navigation.navigate d'afficher un écran A à partir de l'écran D, il y aura une erreur indiquant qu'il ne connaît pas l'écran A, uniquement les écrans C et D.

Je sais que cela a été demandé sous diverses formes à différents endroits sur ce site, ainsi que dans 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 fondamental, il manque des réponses claires et il est difficile de faire défiler les centaines de commentaires GitHub à la recherche d'une solution . 

Peut-être que cette question peut codifier comment faire cela pour tous ceux qui se heurtent à ce problème très courant.

8
izikandrw

Vous pouvez utiliser le paramètre third de navigate pour définir des sous-actions.

Par exemple, si vous souhaitez 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' }))

Assurez-vous également de consulter la section Common errors de la documentation v2 si vous utilisez des navigateurs imbriqués.

11
Stackia

J'ai aussi trouvé une telle solution ici :

onPress={() =>
    Promise.all([
    navigation.dispatch(
        NavigationActions.reset({
            index: 0,
            // TabNav is a TabNavigator nested in a StackNavigator
            actions: [NavigationActions.navigate({ routeName: 'TabNav' })]
        })
    )
    ]).then(() => navigation.navigate('specificScreen'))
}
0
Aliaksei

Réagissez Navigation v3:

Navigation.navigate prend maintenant un objet comme paramètre. Vous définissez le nom de la pile, puis naviguez jusqu'à 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" correspond à votre pile lorsque vous la créez ...

  YOUR_STACK: createStackNavigator({ subRoute: ... })
0
Phil Andrews

Liberté totale: singleton avec options de navigation

Si vous avez plusieurs piles de navigation et sous-piles de navigation, il peut être frustrant de savoir comment obtenir une référence à la pile souhaitée en fonction de la configuration de React Navigation. Si vous pouviez simplement référencer une pile particulière à un moment donné, cela serait beaucoup plus facile. Voici comment.

  1. Créez un singleton spécifique à la pile que vous souhaitez référencer n'importe où.
    // drawerNavigator.js . (or stackWhatever.js)
    const nav = {}
    export default {
      setRef: ref => nav.ref = ref,
      getRef: () => nav.ref
    }

2. Sur l'écran enfant d'une pile, obtenez une référence à sa propriété. Navigation

    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. Maintenant, vous pouvez référencer 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

À l'étape 2, un navigateur d'onglets est l'un des écrans d'un navigateur de tiroir. Onglet Navigateur doit fermer le tiroir, mais également n'importe où dans votre application, vous pouvez appeler drawerNavigator.getRef().closeDrawer() après avoir effectué cette étape.

0
Jason Sebring

Alors que je travaillais sur un projet réactif, je me suis retrouvé dans la même situation. J'ai essayé plusieurs façons de naviguer vers l'écran mais j'ai échoué.

Après de nombreux essais, j'ai essayé de transmettre un objet de navigation parent à un enfant et j’ai passé un appel de fonction de navigation et cela a fonctionné.

En ce qui concerne vos problèmes, si vous souhaitez naviguer d’un écran D à un écran A, suivez ces étapes.

-> Transmettez à ses enfants les accessoires de navigation imbriqués du navigateur 2 à l'aide de 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 chez les enfants en utilisant 

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

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

J'admets que ce processus est peu déroutant mais je ne trouvais aucune solution alors je devais y aller car je devais compléter mon exigence. 

0
HungrySoul