React Navigation: переход назад к корню с помощью NavigationActions.reset, goBack и getStateForAction
Скажем, что я прошел через 4 экрана в моем приложении StackNavigator и теперь хочу вернуться к первому экрану. Кажется, есть три разных способа сделать это, и они перемещаются туда, где я хочу, но каждый из них имеет анимацию, которая проходит через каждый предыдущий экран.
Есть ли чистый способ перехода от SCREEN_D
в SCREEN_A
?
Другими словами, я не хочу видеть SCREEN_C
и SCREEN_B
раскол секунды, прежде чем видеть SCREEN_A
при навигации по назад от SCREEN_D
navigation.navigate(SCREEN_A);
...
navigation.navigate(SCREEN_B);
...
navigation.navigate(SCREEN_C);
...
navigation.navigate(SCREEN_D);
Три способа сделать это:
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
Здесь быстрое решение. Это удалит ВСЕ переходы при навигации (вперед или назад).
const Nav = StackNavigator({
Screens
},{
transitionConfig,
navigationOptions
});
в transitionConfig добавить это:
const transitionConfig = () => ({
transitionSpec: {
duration: 0,
timing: Animated.timing,
easing: Easing.step0,
},
})
TransitionConfig - это функция, которая возвращает объект, который переопределяет переходы экрана по умолчанию. https://reactnavigation.org/docs/navigators/stack
- если бы кто-нибудь знал, как изменить анимацию при одиночной навигации, я бы хотел услышать, как это сделать!
Ответ 2
Вы можете сделать это, используя метод popToTop
из Navigation prop. Кроме того, если вы используете redux, вы должны обновить интеграцию Redux.
Надеюсь это поможет!
Ответ 3
И потратил некоторое время на это, позвольте мне подвести итог тому, что я обнаружил, для этого есть несколько решений/обходных решений:
1) Используйте CardStackStyleInterpolator
тянуть запрос, упомянутый Криштиану Сантос, похоже, слит. Таким образом, вы можете загрузить CardStackStyleInterpolator
с помощью этого импорта:
import CardStackStyleInterpolator from 'react-navigation/src/views/CardStack/CardStackStyleInterpolator'
Чтобы применить его так:
const YourStackNavigator = StackNavigator({
Screen1: { screen: Screen1 },
Screen2: { screen: Screen2 },
}, {
transitionConfig: () => ({
screenInterpolator: (props) => CardStackStyleInterpolator.forHorizontal(props)
})
});
В моем случае я просто перехожу на следующий экран, например:
this.props.navigation.navigate('Modal_AddGoodClass');
Но в моем редукторе я reset навигатор, когда запускается экран Modal_AddGoodClass
:
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;
Это работает очень хорошо, кроме факта, что вместо "передового" используется еще "задняя" анимация.
Вы также можете найти здесь примерный код, который использует CardStackStyleInterpolator
.
2) Перезаписать getStateForAction
:
Как Fendrian упоминается здесь вы можете перезаписать getStateForAction
своего маршрутизатора, чтобы навигатор не вернулся. Кажется, что это работает, за исключением жестов "салфетки назад" на 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);
};
![nov-05-2017 11-34-07]()
Ответ 4
Это мое рабочее решение для reset back to home (root) без создания нового маршрута
if(this.categoriesNav.state.nav.index >0){
let k = this.categoriesNav.state.nav.routes[1].key;
this.categoriesNav.dispatch(NavigationActions.back({key: k})); }
categoriesNav
ссылается на мой навигатор стека
Ответ 5
popToTop
навигация имеет popToTop
мы можем использовать его как удар
this.props.navigation.popToTop()