Search code examples
react-nativereact-native-tabnavigator

Accessing screen properties


I'm experimenting with React Natives createBottomTabNavigator. I'm currently rendering screens as shown in the documentation. I wish to extend this by using icons, but I want to do it differently to as shown in the documentation.

For each screen i'm defining a navigationProperty object, which holds an icon and other information.

I'm defining my tabNavigator as follows:

export default createBottomTabNavigator({
    About: { 
        screen: AboutScreen
    },
    LoyaltyCard: { 
        screen: LoyaltyCardScreen 
    },
    Contact: { 
        screen: ContactScreen 
    },
});

I wish to use the defaultNavigationOptions property to add icons, but rather then define them in the function I wish to use the properties as defined in each screen. For understanding, here's the AboutScreen code.

class AboutScreen extends React.Component {    

    navigationOptions = {
        tabBarLabel: 'About',
        tabBarIcon: 'md-checkmark-circle'
    };

    render() {
        return (
          <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
            <Text>About!</Text>
          </View>
        );
    }     
}

As we can see in the above code example i'm defining two properties in the navigationOptions object. A label and icon. My question is, how can I use these defined properties in the defaultNavigationOptions configuration? Is this even possible?

This is where i'm currently at with the configuration:

defaultNavigationOptions: ({ navigation }) => ({
        tabBarIcon: ({ focused, tintColor }) => {
            console.log(focused)
            return <Ionicons name={navigation.tabBarIcon} size={24} color="green" />;
        },
      })

Thanks


Solution

  • So, I ended up solving this by creating an object of configurations outside of each screen. It looks like this:

    iconInformation = [
        {
            'route': 'About', 
            'default': 'md-help-circle', 
            'focused': 'md-help-circle-outline'
        },
        {
            'route': 'LoyaltyCard', 
            'default': 'ios-ribbon', 
            'focused': 'md-ribbon'
        },
        {
            'route': 'Contact', 
            'default': 'ios-information-circle', 
            'focused': 'ios-information-circle-outline'
        }
    ]
    

    And I use it as follows:

    defaultNavigationOptions: ({ navigation }) => ({
            tabBarIcon: ({ focused, tintColor }) => {
                iconName = ''
                const { routeName } = navigation.state;
                iconInformation.some(function(iconData)  {
                    if(routeName === iconData.route) {
                        iconName = focused ? iconData.focused : iconData.default;
                        return true;
                    }
                });
                return <Ionicons name={iconName} size={24} color="green" />;
            },
          })
    

    I use the some function to do a short-circuit type loop. As this function is used a lot I want to minimize the number of loops. Thinking about it, I could probably shorten this quite a lot by using a custom dictionary object and then access the icon information via the route key, as these match up with the routeName value which gets returned from the navigation.state.