问题
Say I've navigated through 4 screens in my StackNavigator App and now I want to go back to the first screen. There seems to be three different ways to do this and they do navigate to where I want to do, however each way has an animation that cycles through each previous screen.
Is there a clean way to navigate from SCREEN_D
to SCREEN_A
?
In other words, I don't want to see SCREEN_C
and SCREEN_B
a split of a second before seeing SCREEN_A
when navigating backwards from SCREEN_D
navigation.navigate(SCREEN_A);
...
navigation.navigate(SCREEN_B);
...
navigation.navigate(SCREEN_C);
...
navigation.navigate(SCREEN_D);
Three ways to do this:
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);
}
回答1:
react-native navigation has popToTop
we can use it like blow
this.props.navigation.popToTop()
回答2:
Here's a quick fix. This will remove ALL transitions when navigating (forward or backward).
const Nav = StackNavigator({
Screens
},{
transitionConfig,
navigationOptions
});
in transitionConfig add this:
const transitionConfig = () => ({
transitionSpec: {
duration: 0,
timing: Animated.timing,
easing: Easing.step0,
},
})
The transitionConfig is a function that returns an object that overrides default screen transitions. https://reactnavigation.org/docs/navigators/stack
- if someone knows a way to change animations on single navigation, I'd love to hear how!
回答3:
You can do this by using the popToTop
method from the Navigation prop. Also, if you are using redux, you should update your Redux integration.
Hope this helps!
回答4:
Also spent some time on this, let me sum up what I discovered, there are multiple solutions/workarounds for this:
1) Use CardStackStyleInterpolator
The pull request mentioned by Cristiano Santos seems to be merged. So you can load the CardStackStyleInterpolator
with this import:
import CardStackStyleInterpolator from 'react-navigation/src/views/CardStack/CardStackStyleInterpolator'
To apply it like this:
const YourStackNavigator = StackNavigator({
Screen1: { screen: Screen1 },
Screen2: { screen: Screen2 },
}, {
transitionConfig: () => ({
screenInterpolator: (props) => CardStackStyleInterpolator.forHorizontal(props)
})
});
In my case, I just jump to the next screen like:
this.props.navigation.navigate('Modal_AddGoodClass');
But in my reducer, I reset the navigator when the Modal_AddGoodClass
screen is triggered:
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;
This works pretty well, except the fact, that still a "back" animation is used instead of a "forward" one.
You can also find here some example code that uses CardStackStyleInterpolator
.
2) Overwrite getStateForAction
:
As Fendrian mentioned here you can overwrite getStateForAction
of your router to avoid the navigator to go back. This seems to work except for the "swipe back" gesture on 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);
};

回答5:
This is my working solution for reset back to home (root) without creating new 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
is referenced to my stack navigator
来源:https://stackoverflow.com/questions/43946437/react-navigation-navigate-back-to-root-using-navigationactions-reset-goback-an