What I'm essentially trying to accomplish here is to merge these two tutorials (x)(x) in order to create a simple TabBar that has custom icons. I'm trying to use icons from the react-native-vector-icons library, which I've added to my node modules. However, I'm running into a snag:
Invariant Violation: Element type is invalid: expected a string (for built-in >components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
Check the render method of ProfileTabs.
This error is located at: in RCTTabBar (at TabBarIOS.ios.js:82)
in TabBarIOS (at App.js:19)
in ProfileTabs (at App.js:80)
in ProfileApp (at registerRootComponent.js:35)
in RootErrorBoundary (at registerRootComponent.js:34)
etc. Here's the relevant code:
import React, { Component } from 'react';
import { AppRegistry, Image, StyleSheet, TabBarIOS, Text, View } from 'react-native';
import Icon from 'react-native-vector-icons/Ionicons';
var Profile = require('./profile');
var Repositories = require('./repositories');
var Following = require('./following');
var Followers = require('./followers');
class ProfileTabs extends Component {
constructor(props) {
super(props);
this.state = {
selectedTab: 'profile'
};
}
render() {
return (
<TabBarIOS
selectedTab={this.state.selectedTab}>
<Icon.TabBarIOS
selected={this.state.selectedTab === 'profile'}
title="Profile"
iconName='ios-home-outline'
onPress={() => {
this.setState({
selectedTab: 'profile',
});
}}>
<Profile/>
</Icon.TabBarIOS>
<Icon.TabBarIOS
selected={this.state.selectedTab === 'repositories'}
title='Repos'
iconName='ios-home-outline'
onPress={() => {
this.setState({
selectedTab: 'repositories',
});
}}>
<Repositories/>
</Icon.TabBarIOS>
<Icon.TabBarIOS
selected={this.state.selectedTab === 'following'}
title='Following'
iconName='ios-home-outline'
onPress={() => {
this.setState({
selectedTab: 'following',
});
}}>
<Following/>
</Icon.TabBarIOS>
<Icon.TabBarIOS
selected={this.state.selectedTab === 'followers'}
title='Followers'
iconName='ios-home-outline'
onPress={() => {
this.setState({
selectedTab: 'followers',
});
}}>
<Followers/>
</Icon.TabBarIOS>
</TabBarIOS>
)
}
}
export default class ProfileApp extends Component {
render() {
let pic = {
uri: 'https://news.artnet.com/app/news-upload/2015/08/mona-lisa_2-e1440166499927.jpg'
};
return (
<View style={styles.basic_info}>
<Image source={pic} style ={styles.circle_image}/>
<Text style={styles.name_text}>LM</Text>
</View>,
<ProfileTabs/>
);
}
}
I attempted some of the fixes here, but for a lot of the answers there I was unsure of the reasoning behind the given solution, and was confused as to how to apply it to my own code. If I use TabBarIOS.Item elements rather than Icon.TabBarIos elements, and use SystemIcons rather than the library icons, everything works fine, so I suspect the problem lies with how I'm importing/using react-native-vector-icons.
If there's a simpler way to accomplish all this, I'd be open to rewriting my code as well.
As mentioned in the library code Ionicons.js, there is no named export for TabBarIOS
but for TabBarItemIOS
and TabBarItem
.
Therefore you need to use it as
<TabBarIOS>
<Icon.TabBarItemIOS
title="Home"
iconName="ios-home"
selected={this.state.selectedTab === 'home'}
onPress={() => {
this.setState({
selectedTab: 'home',
});
}}
>
{this.renderContent('#414A8C', 'Home')}
</Icon.TabBarItemIOS>
i.e replace Icon.TabBarIOS
with Icon.TabBarItemIOS
Checkout the example here for more details
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With