How to add badge to tab-bar in react-native?

谁都会走 提交于 2020-12-31 05:39:12

问题


I am using the tabnavigator (createbottomBottomTabNavigator) and need help with the bage count using redux.


回答1:


There is custom way to do this using redux, you can make your custom component using the same :-

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

where,

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>
));

Read here more

Also, official tabnavigation in react native have the support for the same, you can read here more

I hope this helps...Thanks :)




回答2:


You can always create your custom component, in this case, the tab item (<TabBarItem />).

I have created a simple demo, here is the snack link: https://snack.expo.io/@abranhe/tab-badge-count-redux

In this example, you have 3 pages/tabs (apps, navigation, and profile) so you need to manage the notification counter of every one of them. So we start by creating the component, I am using Native Base to have pre-built components. Also, we have the following initial state.

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);

This is just a work-around, and as you see I am creating a component connected to Redux and checking which tab should render depending on the icon name prop. If we have only one tab with notifications, only we needed to access the data on Redux, and automatically render.

We need to create a reducer to handle Increment and Decrement actions

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,
        },
      };
  ...
}

Well also we need to add the created component:

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);

We are using dispatch({ type: 'APPS.INCREMENT' }) to trigger the action that increments the notifcations for the apps tab.

The <NotificationCounter /> component code:

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 = ...


来源:https://stackoverflow.com/questions/59171124/how-to-add-badge-to-tab-bar-in-react-native

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!