reactNative94
reactNative94

Reputation: 371

How to update the state of badge counter in Tab Navigator in react-native

I have used the createBottomTabNavigator for the tab bar. And in the tab-bar on notification the count is shown by custom build badge. The problem is whenever the notification is updated the count on the icon in tab-bar does not change. I have to navigate on click on anyother item to get the count updated. I have used the AsyncStorage to store the count in Notification Component and get that count in custome Component which gets called in tabnavigator.

class TabNotificationCount extends Component {

    constructor(props) {
        super(props);
        this.state = {
            focus: false,
            notificationCount: 0,
        }
    }

    componentWillReceiveProps(nextProps) {
        this.setState({ focus: nextProps.isfocus })
        AsyncStorage.getItem('@count', (err, value) => {
            this.setState({ notificationCount: value })
            console.log("value-notification", this.state.notificationCount);
        })
    }

    render() {
        const { notificationCount } = this.state;
        const icon = this.state.focus ? require('../../../images/bell-active.png') : require('../../../images/bell-active.png');
        return (
            <View style={{ flexDirection: 'row' }}>
                <Image source={icon} style={{ width: 22, height: 22, }} />
                <Text style={{ position: 'absolute', top: -10, right: -15, borderRadius: 10, backgroundColor: 'red', color: '#fff', }}>{" " + notificationCount + " "}</Text>
            </View>
        );
    }

}

Upvotes: 3

Views: 3111

Answers (1)

Moradiya Dharmik
Moradiya Dharmik

Reputation: 11

You have done great job here it helped me , also fixed the problem you have described , what I have did is I have refreshed navigation param to update badge , I am not sure what is the flow of it , but refreshing param did worked for me .

I am having a cart page in app which is allowing items to delete/update, and bottomtabnavigator, so every time item deleted/updated I need to refresh bottom tab cart icon total count . so to achieve it I need to refresh navigation param by setting one of the param value(I think it is not correct way but it did work).

Below are the code snippets that I have used to solve the problem .

In my cartIcon.js

import React, {Component} from 'react';
import {View, TouchableOpacity, ActivityIndicator , Image , AsyncStorage} from 'react-native';
import styles from '../styles';
import Text from '../reuseableComponents/Text';
import Icon from 'react-native-vector-icons/FontAwesome';  

export class IconCart extends Component {


  constructor(props) {
        super(props);
        this.state = {
            // focus: false,
            cartData: [],
        }
  }

   componentWillReceiveProps(nextProps) {
        // this.setState({ focus: nextProps.isfocus })
        AsyncStorage.getItem('cartData', (err, value) => {
            if(value){
                this.setState({ cartData: JSON.parse( value ) })
            }
        })
    }

  render() {
    return (
      <TouchableOpacity 
        activeOpacity={1}
        onPress={()=>{this.props.navigation.navigate('Cart')}}
      >
              { this.state.cartData.length != 0  &&
              <Text
                style={{
                  backgroundColor: 'red',
                  alignSelf: 'flex-end',
                  color: '#fff',
                  fontSize: 8,
                  zIndex: 1,
                  position: 'absolute',
                  width: 15,
                  textAlign: 'center',
                  bottom: 15,
                  height: 15,
                  paddingTop:2,
                  borderRadius: 8,
                  marginLeft:15,
                }}>
                {this.state.cartData.length}
              </Text>
              }            
            <Icon name={"shopping-cart"} color={this.props.color} size={24}/>
       </TouchableOpacity>
    );
  }
}

export default IconCart;

in my cart.js

  addQty = async(id) => {
    this.props.dispatch({type: 'CARTACTION', data: id, action: 'add', cartItems: cartData});//to update and refresh state in component
    await AsyncStorage.setItem('cartData', JSON.stringify(cartData));// set data in async storage
    this.props.navigation.setParams({cart: cartData.length});//to refresh navigation params
  };
  minusQty = async(id) => {
    this.props.dispatch({type: 'CARTACTION', data: id, action: 'sub', cartItems: cartData});
    await AsyncStorage.setItem('cartData', JSON.stringify(cartData));
    this.props.navigation.setParams({cart: cartData.length});
  };
  delItem = async(id) => {
    this.props.dispatch({type: 'CARTACTION', data: id, action: 'remove', cartItems: cartData});
    await AsyncStorage.setItem('cartData', JSON.stringify(cartData));
    this.props.navigation.setParams({cart: cartData.length});
  };

in navigator.js in bottomTabnavigator stack for cart into tab bar icon

    Cart: {
      screen:cartStack,
      navigationOptions:({navigation}) => ({
        tabBarOptions: { 
            activeTintColor: '#142333',
            inactiveTintColor: '#778089',
            // showLabel:false,
            activeBackgroundColor:'#fff',
            inactiveBackgroundColor:'#fff',
            style:{height:64},
            labelStyle:{paddingBottom:10,paddingTop:0,marginTop:0},
        },
        tabBarIcon:({tintColor})=>(  
              // <Icon name="shopping-cart" color={tintColor} size={24}/>  
              <IconCart 
                color={tintColor} 
               />
          )  
       }),
    },

And at the end this is my first stackoverflow answer . So please consider any mistake as a part of a baby step towards community :).  

Upvotes: 1

Related Questions