【问题标题】:Show a tab bar item or not based on Redux state in React Native在 React Native 中根据 Redux 状态显示或不显示标签栏项目
【发布时间】:2019-08-28 15:01:10
【问题描述】:

我有一个带有 React Navigation 的 React Native 应用程序,我需要根据 Redux 状态显示或隐藏一个选项卡。我正在使用createBottomTabNavigator 并写了这个:

function createTabNavigator(props:TabNavigatorProps){
  debugger;
  const isClient = WHAT_TO_PUT_HERE??
  const tabs = isClient
  ? {
   //something
  } 
  : {
    //something else
  } 
  return createBottomTabNavigator(
   tabs,
    {
      defaultNavigationOptions: ({ navigation }) => ({
        tabBarIcon: ... ,
        tabBarLabel: ...,
      }
      tabBarComponent: (props) => customTabBar(props, isClient),
      tabBarOptions: {
        ...
      },
    });
};

如果我手动将isClient 设置为truefalse,我的createTabNavigator 会按预期工作,尽管我需要在redux 状态下这样做。

我也尝试过connect,并以正确的状态调用mapStateToProps,但它不会再次调用createTabNavigator,因此状态更改不会更新到我的视图层次结构。

如何根据 Redux 状态添加/删除选项卡(并且实际上完全重新渲染,因为该选项卡还涉及整个栏的一些自定义样式/渲染)?

【问题讨论】:

  • 你不能将你的customTabBar 连接到 redux(想象它是一个不同的组件)并让它知道 redux 当前状态吗?
  • @Auticcat 不,因为选项卡本身是动态的,并且在createTabNavigator 中定义并直接传递给createBottomTabNavigator(并且tabs 根据redux 状态而变化),而tabBarComponent 是一个本身并不真正“了解”选项卡的组件(它只是检查isClient 并通过包裹它在选项卡栏周围添加一些视觉装饰,而不触及实际选项卡栏的内部)。

标签: react-native redux react-navigation


【解决方案1】:

react-navigation 不提供任何 API 来从 BottomTabNavigator 隐藏选项卡。

但是,它允许提供自定义 TabBarComponent。它还公开了 BottomTabBar 组件,该组件是 BottomTabNavigator 的默认 TabBarComponent。

此 BottomTabBar 组件采用属性 getButtonComponent 来获取用于呈现每个选项卡的组件。它在参数中提供选项卡详细信息,并预计返回用于呈现该选项卡的组件。

要实现动态隐藏选项卡,您可以为 getButtonComponent 提供自己的函数。使用您的状态检查选项卡的详细信息,以决定它应该是可见的还是隐藏的。如果要隐藏它,则返回一个“空组件”,否则只需调用默认值。

/**** Custom TabBarComponent ****/
const BlackHole = (props) => []
let _TabBarComponent = (props) => {
  const getButtonComponent = (arg) => {
    const hide = props.hiddenTabs[arg.route.key];
    if (hide) {
      return BlackHole;
    }
    return props.getButtonComponent(arg)
  }
  return (<BottomTabBar {...props} getButtonComponent={getButtonComponent}/>);
};

const mapStateToProps = (state) => ({
  hiddenTabs: state.hiddenTabs
});

const TabBarComponent = connect(mapStateToProps)(_TabBarComponent);

/**** Navigation ****/
const TabNavigator = createBottomTabNavigator({
  Tab1: createStackNavigator({Screen1}),
  Tab2: createStackNavigator({Screen2}),
  Tab3: createStackNavigator({Screen3}),
}, {
  tabBarComponent: props => (
    <TabBarComponent {...props} style={{borderTopColor: '#605F60'}}/>
  )
});

查看此点心了解 POC:https://snack.expo.io/BJ80uiJUH

【讨论】:

    【解决方案2】:

    我们有同样的要求,但是在 react 导航中我们不能有动态选项卡,因为我们必须提前静态定义好所有路由。

    查看answer,我在其中详细解释了我们是如何实现它的。

    还提到了其他可能的方法(我们还没有这样做)。

    还有一个更有趣的article,你可能想看看这个。

    【讨论】:

      【解决方案3】:

      确保你没有在 HOC 组件中调用 redux 状态, 对于状态管理,你可以尝试在组件中渲染它,试试这个逻辑:

      class TabIndex extends Component {
              render() {
                   // coming from redux
                  let isClient= this.props.isClient;
      
              return (<View>
                      {isClient?<TabIndexNavigator ifYouNeed={ isClient } />
                       :
                      null}
                      </View>)
          }
       }
      
      module.exports = TabIndex
      

      然后在您的主 stackNavigator 中正常导入它

      const StackMain = StackNavigator(
          {
              TabIndex: {
                  screen: TabIndex
              },
              ...
      }
      

      【讨论】:

        猜你喜欢
        • 2020-06-08
        • 1970-01-01
        • 2021-03-21
        • 2014-10-10
        • 2015-07-25
        • 2021-03-08
        • 1970-01-01
        • 2018-11-16
        • 2016-07-31
        相关资源
        最近更新 更多