Как заменить вложенный стек другим компонентом в react-native-navigation v2?

#react-native-navigation #wix-react-native-navigation #react-native-navigation-v2

#react-native-navigation #wix-react-native-navigation #react-native-navigation-v2

Вопрос:

Я пытаюсь создать динамический мастер с помощью react-native-navigation v2.
Я говорю динамический, потому что количество шагов может варьироваться в зависимости от того, какие параметры выбирает пользователь.

Я думал использовать вложенные стеки, чтобы макет моего приложения выглядел примерно так:

 {
  root: {
    sideMenu: {
      left: {/*...*/},
      center: {
        stack: {
          children: [component1, /*...,*/ componentX]
        }
      }
    }
  }
}
  

С ComponentX я запускаю свой мастер, поэтому я создаю новый стек следующим образом:

 {
// ...
  stack: {
    children: [
      component1,
      //...,
      componentX,
      {
        stack: {
          children: [step1, step2, /*...,*/ stepN]
        }
      }
    ]
  }
}
  

После того, как пользователь сделает последний выбор в stepN, я хотел бы заменить вложенный стек на экран сводки, чтобы было что-то вроде:

 {
//...
  stack: {
    children: [
      component1,
      //...,
      componentX,
      summaryScreen
    ]
  }
}
  

Я мог бы использовать Navigation.setRoot для сброса всего этого, но это означает, что мне, вероятно, пришлось бы сохранить навигацию в Redux.
Я также пробовал использовать Navigation.setStackRoot , но у меня сложилось впечатление, что он устанавливает корневой каталог родительского стека, а не мой вложенный стек…

Ответ №1:

Мне наконец-то удалось это решить.
Вот как:

  1. При запуске моего приложения, когда я даю идентификатор моему основному стеку
 const sideMenu = {
    left: { /*...*/ },
    center: {
      stack: {
        id: 'main', // this line is important
        children: [/*...*/]
      }
    },
  };
  Navigation.setRoot({
    root: { sideMenu },
  });
  
  1. Когда я хочу запустить свой мастер, я запускаю новый стек
 Navigation.push(componentId, {
  stack: {
    id: 'wizard',
    children: [
      {
        component: { /*...*/ },
      },
    ],
  }
})
  
  1. Я нажимаю на экраны в новом стеке wizard по мере продвижения пользователя

  2. Когда я хочу отобразить итоговый сводный экран, я вызываю setStackRoot во вложенном стеке

 Navigation.setStackRoot('wizard', [
  {
    component: { /*...*/ },
  },
]);
  
  1. На этом итоговом экране у меня есть кнопка с надписью «Готово», которая удаляет вложенный стек
 Navigation.pop('main');
  

РЕДАКТИРОВАТЬ: только при таком подходе, если вы нажмете на стрелку назад, когда вы находитесь на вложенном экране, он удалит весь вложенный стек вместо только этого экрана.
Мне пришлось использовать пользовательскую кнопку «Назад» следующим образом:

Я решил это с помощью пользовательской кнопки «Назад»: 1. При нажатии на новый экран, где я хочу переопределить кнопку, используйте параметры

 import Icon from 'react-native-vector-icons/MaterialIcons';
/* ... */
const backIcon = await Icon.getImageSource('arrow-back', 24, '#000');
const component = {
  id: screenID,
  name: screenID,
  passProps,
  options: {
    topBar: {
      leftButtons: [
        {
          id: 'backButton',
          icon: backIcon,
        },
      ],
    },
  }
};
return Navigation.push(componentId, { component });
  
  1. Создайте специальное приложение для реализации вашего пользовательского обратного действия
 import React, { Component } from 'react';
import { Navigation } from 'react-native-navigation';

const getDisplayName = WrappedComponent => WrappedComponent.displayName || WrappedComponent.name || 'Component';

export default function withCustomBackButton(WrappedComponent) {
  class WithCustomBackButton extends Component {
    componentDidMount() {
      this.navigationEventListener = Navigation.events().bindComponent(this);
    }

    componentWillUnmount() {
      if (this.navigationEventListener) this.navigationEventListener.remove();
    }

    navigationButtonPressed() {
      // Your custom action
      const { componentId } = this.props;
      Navigation.pop(componentId);
    }

    render() {
      return <WrappedComponent {...this.props} />;
    }
  }

  WithCustomBackButton.displayName = `WithCustomBackButton(${getDisplayName(WrappedComponent)})`;

  return WithCustomBackButton;
}
  
  1. При регистрации экрана с помощью пользовательской кнопки «Назад» оберните его в свой HOC
 import withCustomBackButton from '../components/hoc/WithCustomBackButton';
/* ... */
Navigation.registerComponent('selectLocation', () => withCustomBackButton(SelectLocation));
  

Комментарии:

1. Привет @Gpack, мне нужна помощь в повторной классификации нескольких стеков. В моем приложении более 1000 компонентов и подкомпонентов. Как настроить разделение стека в моем проекте. Я очень смущен тем, как подойти к маршрутизации. Пожалуйста, помогите мне.

2. Привет @HarleenKaurArora, я далек от того, чтобы быть экспертом. Вот ссылка , которая может оказаться полезной для организации вашего приложения