Подтвердить что ты не робот

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);
}
4b9b3361

Ответ 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()