7

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.

lmotl3
  • 537
  • 1
  • 8
  • 20

1 Answers1

1

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

Pritish Vaidya
  • 21,561
  • 3
  • 58
  • 76
  • I've tried what you wrote, copied the example, stripped it from whatever could go wrong, but it still gives me the same error: `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 `TabBarExample`. This error is located at: in RCTTabBar (at TabBarIOS.ios.js:86) ...etc` I feel somehow my imports aren't working. BTW, I'm using `expo init` – Highmastdon Feb 11 '19 at 20:47
  • You can update your question, I’ll have a look at it – Pritish Vaidya Feb 12 '19 at 03:50
  • Also, the error states to check the render method of `TabBarExample`, therefore you need to update and post the complete relevant code, thanks. – Pritish Vaidya Feb 12 '19 at 05:09
  • Alright, so I'm using Expo and I figured out the `@expo/vector-icons` doesn't expose the `TabBarItemIOS` for each iconset. All in all, it's not possible to do this with Expo. I've made an issue which is already closed that shows that they have no plans in exposing it: [expo/vector-icons/issue#81](https://github.com/expo/vector-icons/issues/81) – Highmastdon Feb 12 '19 at 09:06