Supposons que j'ai navigué sur 4 écrans dans mon application StackNavigator et que je souhaite maintenant revenir au premier écran. Il semble y avoir trois façons différentes de le faire et ils naviguent où je veux, cependant chaque animation a une animation qui parcourt chaque écran précédent.
Existe-t-il un moyen simple de naviguer de SCREEN_D
à SCREEN_A
?
En d'autres termes, je ne veux pas voir SCREEN_C
et SCREEN_B
une fraction de seconde avant de voir SCREEN_A
lors de la navigation à partir de SCREEN_D
navigation.navigate(SCREEN_A);
...
navigation.navigate(SCREEN_B);
...
navigation.navigate(SCREEN_C);
...
navigation.navigate(SCREEN_D);
Trois façons de faire ceci:
1.
return this.props.navigation
.dispatch(NavigationActions.reset(
{
index: 0,
actions: [NavigationActions.navigate({ routeName: 'SCREEN_A'})]
}));
2.
const {SCREEN_B_KEY} = this.props.navigation.state.params
this.props.navigation.goBack(SCREEN_B_KEY)
3.
const defaultGetStateForAction = Navigation.router.getStateForAction;
Navigation.router.getStateForAction = (action, state) =>{
if(action.type === "Navigation/BACK"){
const routes = [
{routeName: 'First'},
];
return {
...state,
routes,
index: 0,
};
}
return defaultGetStateForAction (action,state);
}
Voici une solution rapide ... Ceci supprimera TOUTES les transitions lors de la navigation (avant ou arrière).
const Nav = StackNavigator({
Screens
},{
transitionConfig,
navigationOptions
});
dans transitionConfig, ajoutez ceci:
const transitionConfig = () => ({
transitionSpec: {
duration: 0,
timing: Animated.timing,
easing: Easing.step0,
},
})
TransitionConfig est une fonction qui renvoie un objet qui remplace les transitions d'écran par défaut. https://reactnavigation.org/docs/navigators/stack
Vous pouvez le faire en utilisant la méthode popToTop
à partir de Navigation prop . De plus, si vous utilisez redux, vous devez mettre à jour votre intégration Redux .
J'espère que cela t'aides!
Également passé du temps là-dessus, laissez-moi résumer ce que j'ai découvert, il existe plusieurs solutions/solutions de contournement pour cela:
CardStackStyleInterpolator
La demande pull mentionnée par Cristiano Santos semble être fusionnée. Vous pouvez donc charger la CardStackStyleInterpolator
avec cette importation:
import CardStackStyleInterpolator from 'react-navigation/src/views/CardStack/CardStackStyleInterpolator'
Pour l'appliquer comme ceci:
const YourStackNavigator = StackNavigator({
Screen1: { screen: Screen1 },
Screen2: { screen: Screen2 },
}, {
transitionConfig: () => ({
screenInterpolator: (props) => CardStackStyleInterpolator.forHorizontal(props)
})
});
Dans mon cas, je passe simplement à l'écran suivant, comme suit:
this.props.navigation.navigate('Modal_AddGoodClass');
Mais dans mon réducteur, je réinitialise le navigateur lorsque l'écran Modal_AddGoodClass
est déclenché:
const NewExportReceiptNavigationReducer = (state, action) => {
// Default stuff
let newStateBuffer = newState || state;
if (action) {
if (action.type === 'Navigation/NAVIGATE') {
if (action.routeName === 'Modal_AddGoodClass') {
newStateBuffer = {
index: 0,
routes: [
newStateBuffer.routes[newStateBuffer.routes.length - 1]
]
};
}
}
}
return newStateBuffer;
};
module.exports = NewExportReceiptNavigationReducer;
Cela fonctionne plutôt bien, sauf le fait qu'une animation "en arrière" est toujours utilisée au lieu d'une animation "en avant".
Vous pouvez également trouver ici des exemples de code utilisant CardStackStyleInterpolator
.
getStateForAction
:Comme Fendrian a mentionné ici , vous pouvez écraser getStateForAction
de votre routeur pour éviter que le navigateur ne retourne. Cela semble fonctionner sauf pour le geste "glisser en arrière" sur iOS:
Nav = StackNavigator(navScreens, navOptions);
const defaultGetStateForAction = Nav.router.getStateForAction;
Nav.router.getStateForAction = (action, state) => {
if (
state &&
action.type === NavigationActions.BACK &&
(
state.routes[state.index].routeName === 'Login' ||
state.routes[state.index].routeName === 'Main'
)
) {
// Returning null indicates stack end, and triggers exit
return null;
}
return defaultGetStateForAction(action, state);
};
Ceci est ma solution de travail pour réinitialiser à la maison (racine) sans créer de nouvelle route
if(this.categoriesNav.state.nav.index >0){
let k = this.categoriesNav.state.nav.routes[1].key;
this.categoriesNav.dispatch(NavigationActions.back({key: k})); }
categoriesNav
est référencé à mon navigateur de pile