【问题标题】:React native : How to open modal or action sheet on clicking a button tab in wix react native navigationReact native:如何在 wix react native 导航中单击按钮选项卡时打开模式或操作表
【发布时间】:2026-01-17 22:45:02
【问题描述】:

如何使用 wix react native navigation v2 通过单击基于选项卡的应用程序的底部选项卡来打开模式/操作表?

目前,我正在使用以下包和版本:

  • 反应原生:“0.59.8”
  • 反应:“16.8.3”
  • react-native-navigation : "^2.13.2"
  • react-native-image-crop-picker: "^0.24.1"

这是我的路线/导航文件

 Promise.all([
        Foundation.getImageSource("home", 40),
        FontAwesome5.getImageSource("user",30),
        Feather.getImageSource("camera",25),
    ]).then(sources => {
        Navigation.setRoot({
            root: {
                sideMenu: {
                    center: {
                        bottomTabs: {
                            options: {
                                bottomTabs: {
                                    backgroundColor: 'white',
                                    titleDisplayMode: 'alwaysHide'
                                },
                            },
                            children: [
                                {
                                    stack: {
                                        children: [{
                                            component: {
                                                name: 'HomeScreen',
                                                passProps: {
                                                    text: 'This is tab 1'
                                                }
                                            }
                                        }],
                                        options: {
                                            bottomTab: {
                                                testID: 'HOME_TAB',
                                                icon: sources[0],
                                            },

                                            topBar: {
                                                title: {
                                                    text: 'MyReactApp',
                                                }
                                            }
                                        }
                                    }
                                },
                                {
                                    component: {
                                        name: 'Camera',
                                        passProps: {
                                            text: 'This is tab 2'
                                        },
                                        options: {
                                            bottomTab: {
                                                testID: 'CAMERA_TAB',
                                                icon: sources[2]
                                            }
                                        }
                                    }
                                },
                                {
                                    stack: {
                                        children: [{
                                            component: {
                                                name: 'ProfileScreen',
                                                passProps: {
                                                    text: 'Profile Screen'
                                                }
                                            }
                                        }],
                                        options: {
                                            bottomTab: {
                                                testID: 'PROFILE_TAB',
                                                icon: sources[1],
                                            },
                                            topBar: {
                                                title: {
                                                    text: 'John Doe',
                                                }
                                            }
                                        }
                                    }
                                }
                                ]
                        },
                    },
                },
            }
        });
    });

我想要的是,当用户单击camera 选项卡时,它应该打开一个模式/操作表,其中将显示他应该从相机胶卷中选择图像还是应该打开相机的选项。为此,我想使用react-native-image-crop-picker。但是我怎样才能做到这一点,或者我怎样才能自定义按钮标签按下操作?

我在谷歌上查看过,但除了这些对我没有多大帮助的链接之外,没有找到任何其他内容

https://github.com/wix/react-native-navigation/issues/3238

https://github.com/wix/react-native-navigation/issues/2766

https://github.com/wix/react-native-navigation/issues/3204

【问题讨论】:

  • 使用导航事件在选项卡上显示和隐藏模式/操作表。
  • 怎么样?我希望它打开一个模式而不是新页面我该怎么做你能分享一个例子或其他东西。
  • Navigation events 参考此链接。你必须使用模态,当组件可见时可见,屏幕不可见时隐藏。

标签: javascript reactjs react-native wix-react-native-navigation


【解决方案1】:

据说v2的文档比v1的版本差。我正在使用这个包。大多数情况下,我会尝试通过查看源代码来解决我无法解决的问题。我必须说它很有用。这有点挑战性,但确实很有帮助。

值得再次记住; 在 React 结构中,一切都是组件

有很多方法; (现在想到什么)

  1. 您创建自己的组件并将其连接到bottomTab。当这个组件被触发时,你可以显示wix的modal或者react-native的modal。
  2. 虽然以上内容仍然有效;你可以用 passProps 来做。但请记住,当您执行此操作时,您链接到 bottomTab 的页面也会出现。

作为一种解决方案;

您不必使用 Wix 的模式。坦率地说,我不喜欢它,因为我期待 Bootstrap 的模态风格,我使用的是 react-native 自己的模态。这是你的决定。

您可以使用我编写的任何 bottomTab 解决方案,也可以自己创建解决方案。 Wix 为此提供了很大的可能性。

您还可以在模态框内添加可触摸按钮,并指定是要打开相机还是要打开图库。

我已经在模块的 repo 中看到了示例代码。

如果我无法解释,我可以创建一个示例 repo:/

【讨论】:

  • 你好,是的,我也是这么想的。在这种情况下,使用 wix modal 并不是一个好的解决方案,但我仍然无法这样做。能否请您分享您编写的解决方案的链接,或者您是否创建了一个对我真的有很大帮助的小型仓库。
【解决方案2】:

一种方法是使用 componentDidAppear 事件。每次将组件附加到视图层次结构(因此,出现)时,都会调用此事件。它的使用方式或多或少与 React Native 生命周期 API(例如 componentDidMount)相同,不同之处在于您需要“监听”它,根据文档,componentDidMount() (https://wix.github.io/react-native-navigation/#/docs/events?id=componentdidappear)

然后,您可以在 Camera 组件的 componentDidAppear() 中使用一些逻辑来显示模态或叠加层,并将函数作为 prop 传递以更改 Camera 组件的状态并根据选择进行渲染。以下示例使用 RNN 文档中的 componentDidAppear() 示例。免责声明,我没有测试它,但它应该可以工作。

class Camera extends Component {
  constructor(props){
      super(props);

      // Don't forget to bind the setMode function
      this.setMode = this.setMode.bind(this);

      // Edit: catch the tabchange
      this.eventSubscription = Navigation.events().registerBottomTabSelectedListener(this.tabChanged);

      this.state = {
         mode: 'default'
      }
  }

  componentDidMount() {
    this.navigationEventListener = Navigation.events().bindComponent(this);
  }

  componentWillUnmount() {
    // Not mandatory
    if (this.navigationEventListener) {
      this.navigationEventListener.remove();
    }
  }

  componentDidAppear() {
      Navigation.showModal({
          component: {
              // Example name, don't forget to register the modal screen
              name: 'modals.ImageModeChoiceModal',
              passProps: {
                  setMode: this.setMode,
                  // Edit pass the index of the unselected tab to the modal
                  fromTab: this.fromTab
              }
           }
      });
  }

  setMode(mode){
      this.setState({
          mode: mode
      });
  }

  // Edit: callback that will be fired on the bottomTabSelectedListener
  // Tracks the selected and unselected tab index
  tabChanged = (selectedTabIndex, unselectedTabIndex}) => {
      this.fromTab = unselectedTabIndex;
  }

  render(){
      if(this.state.mode === "camera"){
          return( 
                // Camera component
          );
      } else if(this.state.mode === "roll"){
          return( 
                // Camera roll component
          );
      } else {
          return(
                // Default component
                // You could also choose to implement the user choice logic 
                // here
          )
      }
  }
}

编辑:作为后续问题,处理后退导航行为出现了问题。在 backpress 或 modalclose 上,模态关闭并最终转到 Camera 组件(在本例中为屏幕/选项卡)。这是因为选择了选项卡,并且在相机组件的“出现”时打开了模态。 Navigation 道具不保存有关按下的选项卡的信息。因此,您需要在其他地方获取有关它的信息。您可以在 Camera 组件中添加 Navigation 事件侦听器来拦截选中和未选中的选项卡索引(例如:https://github.com/wix/react-native-navigation/issues/4109,文档:https://wix.github.io/react-native-navigation/#/docs/events?id=registerbottomtabselectedlistener

在模态组件中,您应该添加一些逻辑来处理后推/后退行为(来源:https://facebook.github.io/react-native/docs/backhandler.html):

  ...

  componentDidMount() {
    this.backHandler = BackHandler.addEventListener('hardwareBackPress', this.handleBackPress);
  }

  componentWillUnmount() {
    this.backHandler.remove()
  }

  handleBackPress = () => {
    this.closeModal();
    return true;
  }

  // Can also be used to implement close button behaviour (eg. on iOS)
  closeModal(){

      // Dismiss the modal itself
      Navigation.dismissModal(this.props.componentId);

      // This changes the active tab programmatically
      // Don't forget to add a bottomTabsId to your bottomTabs configuration
      Navigation.mergeOptions('bottomTabsId', {
          bottomTabs: {

              // Using the index of the unselected tab passed from the Camera component
              currentTabIndex: this.props.fromTab
          }
      });
  }

  ...

ps:根据 RNN 文档,dismissModal 将“mergeOptions”作为第二个参数,但我还没有使用或测试过,但这可能意味着 Navigation.mergeOptions 可以集成到 Navigation.dismissModal 调用中。 (文档:https://wix.github.io/react-native-navigation/#/docs/screen-api?id=dismissmodalcomponentid-mergeoptions

【讨论】:

  • 这确实打开了模式,但是当我尝试按下后退按钮时。它返回到相同的相机页面。
最近更新 更多