如何在react-native-navigation v2中用其他组件替换嵌套堆栈?

时间:2019-03-20 07:54:17

标签: 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 个答案:

答案 0 :(得分:0)

我终于设法解决了。
方法如下:

  1. 在我的应用程序启动时,当我给我的主堆栈分配一个ID
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. 创建一个HOC以实施自定义后退操作
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));