如何在另一个 React 组件中正确使用 TabNavigator

Posted

技术标签:

【中文标题】如何在另一个 React 组件中正确使用 TabNavigator【英文标题】:How to properly use TabNavigator inside another React Component 【发布时间】:2018-06-19 10:35:27 【问题描述】:

问题 - 如何在另一个充当包装器组件的 React 组件中正确使用 React Navigation 的 TabNavigator 容器组件?

我想要实现的目标 - 基本上我希望 appbar 和 tabbar 都显示 - appbar 在顶部,tabbar (TabBarTop) 就在它的下方,这是一种非常常见的设计模式。

我尝试了几种方法。

方法#1(嵌套在 StackNavigator 中)

Tab.js

export const Tab = TabNavigator(
    Tab1:  screen: Tab1Container ,
    Tab2:  screen: Tab2Container 
  , 
    tabBarComponent: TapBarTop,
    tabBarPosition: 'top'
  );

AppBar.js

class AppBarComponent extends Component 
  static navigationOptions =  header: null 
  render() 
    return (
      <View>
        *some more views, buttons blah blah here
      </View>
    )
  

export default AppBarComponent;

我在 StackNavigator 中使用它们,比如

export default StackNavigator(
  stack1:  screen: AppBarComponent ,
  stack2:  screen: Tab 
);

这导致在给定时间仅显示 1 个堆栈,这正是它的工作原理。而且我和initialRouteName没有任何关系。

方法#2(包装在另一个组件中)

<View style= flex: 1 >
  <AppBarComponent />
  <Tab />
</View>

这相反显示两个组件,但 this.props.navigation.navigate('somepath')push()pop() em> 或 replace() 在内部和 .但是 this.props.navigation 及其方法都可以在这些组件中使用。

PS - 我正在使用 React Navigation v1 并在 ios 上运行

【问题讨论】:

【参考方案1】:

方法一的解决方案

拥有一个只有一个屏幕的StackNavigator,并在该屏幕上显示您的TabNavigator。然后使用您的自定义AppBarComponent 自定义header

标题

给定 HeaderProps 的 React 元素或函数返回一个 React 元素,显示为标题。设置为null 隐藏标题。

示例

export default StackNavigator(
  stack:  
    screen: Tab,
    navigationOptions: 
      header: (HeaderProps) => (<AppBarComponent headerProps=HeaderProps />)
    
  
);

方法2的解决方案

您可以使用withNavigation HOC 包装不属于堆栈的组件。

withNavigation 是一个高阶组件,它通过 导航道具进入包装的组件。当你不能时它很有用 直接将导航道具传递给组件,或者不想 在嵌套很深的孩子的情况下传递它。

示例

class AppBarComponent extends Component 
  static navigationOptions =  header: null 
  render() 
    return (
      <View>
        *some more views, buttons blah blah here
      </View>
    )
  

export default withNavigation(AppBarComponent);

【讨论】:

【参考方案2】:

@bennygenel 您的回答对于解决问题绝对有用。当我谈到在 TabNavigator 中包含组件时,我提供了错误的信息。好吧,TabNavigator 内部有多个 redux 容器作为屏幕而不是哑组件,而整个 TabNavigator 包装在一个哑组件中。我真诚地编辑了我的问题。

虽然 this.props.navigation 存在于 redux 容器和包装器组件中,但导航堆栈引用对它们来说是不同的,这就是 navigategoBack() 等方法不起作用的原因。

解决方案很简单。将导航堆栈引用作为screenProps 传递给包装器组件可以解决此问题。

<View style= flex: 1 >
  <AppBarComponent />
  <Tab screenProps= rootNav: this.props.navigation  />
</View>

【讨论】:

以上是关于如何在另一个 React 组件中正确使用 TabNavigator的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 React Hooks 在另一个组件中获取表单的输入值

在后台从 React 组件制作 HTML 字符串,如何在另一个 React 组件中通过危险的SetInnerHTML 使用该字符串

React 如何订阅在另一个组件中声明的可观察对象

React Native:在另一个组件之上的组件

如何在另一个带有 props 的组件中使用 useState 函数?

在另一个 bean 中使用来自一个 bean(组件)的方法是不是正确?