如何在react-native中将徽章添加到选项卡栏?

时间:2019-12-04 07:41:40

标签: react-native redux react-redux react-native-navigation

我正在使用tabnavigator(createbottomBottomTabNavigator),需要使用redux进行袋计数的帮助。

2 个答案:

答案 0 :(得分:1)

有一种使用redux的自定义方法,您可以使用相同的自定义组件:-

screen: NotificationScreen,
    navigationOptions: {
      tabBar: (state, acc) => ({
        icon: ({ tintColor, focused }) => (
          <BadgeTabIcon
            iconName="notification"
            size={26}
            selected={focused}
          />
        ),
        visible: (acc && acc.visible !== 'undefined') ? acc.visible : true,
      }),
    },
  },

哪里

export default connect(state => ({
  notificationCount: state.notifications.count,
}))(({ dispatch, nav }) => (
  <View>
    <TabIcon {...props} />
    {
      props.notificationCount > 0 ?
        <View style={{ position: 'absolute', right: 10, top: 5, backgroundColor: 'red', borderRadius: 9, width: 18, height: 18, justifyContent: 'center', alignItems: 'center' }}>
          <Text style={{ color: 'white' }}>{props.notificationCount}</Text>
        </View> : null
    }
  </View>
));

在此处阅读more

此外,react native中的官方导航也支持该功能,您可以阅读here更多

我希望这可以帮助...谢谢:)

答案 1 :(得分:1)

您始终可以创建自定义组件,在这种情况下,可以创建选项卡项目(<TabBarItem />)。

我创建了一个简单的演示,这是小吃链接:https://snack.expo.io/@abranhe/tab-badge-count-redux

在此示例中,您有3个页面/选项卡(应用程序,导航和个人资料),因此您需要管理每个页面/选项卡的通知计数器。因此,我们从创建组件开始,我正在使用Native Base来预先构建组件。另外,我们具有以下初始状态。

export default {
  apps: {
    notificationCount: 7,
  },
  navigation: {
    notificationCount: 0,
  },
  profile: {
    notificationCount: 3,
  },
};

TabBarItem.js

import React from 'react';
import { connect } from 'react-redux';
import { View, StyleSheet } from 'react-native';
import { Badge, Button, Icon, Text } from 'native-base';

const renderBadge = ({ badgeProps, counter }) => (
  <Badge {...badgeProps} style={styles.badge}>
    <Text style={styles.notificationText}>{counter}</Text>
  </Badge>
);

function TabBarItem({ notificationCount, badgeProps, icon, label, color }) {
  let counter = 0;

  switch (icon) {
    case 'apps':
      counter = notificationCount.apps;
      break;
    case 'navigate':
      counter = notificationCount.navigation;
      break;
    case 'person':
      counter = notificationCount.profile;
      break;
    default:
      counter = 0;
  }

  return (
    <View style={styles.container}>
      {counter > 0 && renderBadge({ counter, badgeProps })}
      <View style={styles.iconContainer}>
        <Icon name={icon} style={{ color }} />
        <Text style={{ color, ...styles.label }}>{label}</Text>
      </View>
    </View>
  );
}

const styles = ....;

const mapStateToProps = state => ({
  notificationCount: {
    apps: state.apps.notificationCount,
    navigation: state.navigation.notificationCount,
    profile: state.profile.notificationCount,
  },
});

export default connect(mapStateToProps)(TabBarItem);

这只是一个变通方法,正如您所看到的,我正在创建一个连接到Redux的组件,并根据图标名称prop来检查应呈现哪个选项卡。如果我们只有一个带有通知的标签,则只需要访问Redux上的数据并自动呈现。

我们需要创建一个reducer来处理Increment和Decrement操作

export default function reducer(state = initialState, action = {}) {
  switch (action.type) {
    case 'APPS.INCREMENT':
      return {
        ...state,
        apps: {
          ...state.apps,
          notificationCount: state.apps.notificationCount + 1,
        },
      };

    case 'APPS.DECREMENT':
      return {
        ...state,
        apps: {
          ...state.apps,
          notificationCount: state.apps.notificationCount - 1,
        },
      };
  ...
}

我们还需要添加创建的组件:

import React from 'react';
import { connect } from 'react-redux';
import { StyleSheet } from 'react-native';
import { Container, Content, H1, H3 } from 'native-base';
import NotificationCounter from '../components/NotificationCounter';

const Apps = ({ notificationCount, dispatch }) => (
  <Container>
    <Content contentContainerStyle={styles.container}>
      <H1>Apps Page</H1>
      <NotificationCounter
        handleIncrement={() => dispatch({ type: 'APPS.INCREMENT' })}
        handleDecrement={() => dispatch({ type: 'APPS.DECREMENT' })}
      />
      <H3>Notification Count: {notificationCount}</H3>
    </Content>
  </Container>
);

const styles = ...

const mapStateToProps = state => ({
  notificationCount: state.apps.notificationCount,
});

export default connect(mapStateToProps)(Apps);

我们正在使用dispatch({ type: 'APPS.INCREMENT' })来触发增加“应用”标签的通知的操作。

<NotificationCounter />组件代码:

import React from 'react';
import { View, StyleSheet } from 'react-native';
import { Button, Text } from 'native-base';

export default ({ handleDecrement, handleIncrement }) => (
  <View style={styles.container}>
    <Button onPress={handleDecrement}>
      <Text>Decrement</Text>
    </Button>
    <Button onPress={handleIncrement}>
      <Text>Increment</Text>
    </Button>
  </View>
);

const styles = ...