Search code examples
javascriptreact-nativereact-navigationreact-navigation-v5

Invariant Violation: Element type is invalid in createMaterialTopTabNavigator()/MaterialTopTabView render method, React Native w/ React Navigation v5


I am seeing the following error when using createMaterialTopTabNavigator() in React Native with React Navigation v5:

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 `MaterialTopTabView`.

The relevant code is as follows. I tried to delete anything extraneous and add ellipses as a placeholder, so apologies if I missed anything important.

Connect.js:

import React, { Component } from 'react';
import { ... } from 'react-native';
import globalStyles from '../Styles/global-styles.js';
import Sessions from './Sessions.js';
import ChatList from './ChatList.js';
import { NavigationContainer } from "@react-navigation/native";
import { createMaterialTopTabNavigator } from '@react-navigation/material-top-tabs';

const TopTabNav = createMaterialTopTabNavigator();
function GetTopTabNavigator() {
    return (
        <NavigationContainer>
            <TopTabNav.Navigator tabBarOptions={{...}}>
                <TopTabNav.Screen name="Chat" component={ChatList}/>
                <TopTabNav.Screen name="Sessions" component={Sessions}/>
            </TopTabNav.Navigator>
        <NavigationContainer/>
    );
};

class ConnectScreen extends Component {
    static router = TopTabNav.router;

    constructor(props) {
        super(props);
        this.state = {
            ...
        };
    }

    ...

    render() {
        ...

        return (
            <SafeAreaView style={{...}}>
                ...
                <View style={globalStyles.container}>
                    GetTopTabNavigator()
                </View>
            </SafeAreaView>
        );
    }
}

export default ConnectScreen;

Research (and the error code) indicates that this is likely an issue with the way that a component is being imported or exported. To this end, I've tried several things:

1. Putting the Top Tab Navigator in a separate file, then exporting it (both as default and not with the appropriate brackets {} in the import statement) — any combinations results in either this error or another, for which the solution is to switch back to this way.

2. Copying the exact code from the documentation (https://reactnavigation.org/docs/material-top-tab-navigator/), pasting it in ConnectTopTabNav.js, then importing it using

import ConnectTopTabNav from './ConnectTopTabNav';

ConnectTopTabNav, too, I tried exporting as default and not as default, with the above corresponding to the former (shown below). Here is the code for ConnectTopTabNav.js:

import * as React from 'react';
import { Text, View } from 'react-native';
import { createMaterialTopTabNavigator } from '@react-navigation/material-top-tabs';

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

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

const Tab = createMaterialTopTabNavigator();
export default function TobTabNav() {
    return ( 
        <Tab.Navigator>
            <Tab.Screen name="Home" component={HomeScreen} />
            <Tab.Screen name="Settings" component={SettingsScreen} />
        </Tab.Navigator>
    );
}

However, the same problem results in Connect.js regardless of whether I attempt to render the component as ConnectTopTabNav() or . I also tried putting the above code directly into Connect.js, to no avail.

3. Looking through the @react-navigation/material-top-tabs file structure for any import/export errors. Didn't find anything, which isn't too surprising.

4. Putting the navigator inside my App.js navigation structure in several fashions. Also a dead end.

5. Surrounding the navigator with the < NavigationContainer /> component, with the corresponding flag to indicate that it's independent of the main navigator. (Edit: I've added this to the code to reflect this change.)

The error has arisen since upgrading to @react-navigation version 5. In version 4, I was able to create the navigator within the createMaterialTopTabNavigator() method directly, and didn't see an error.

I am using version 5.4.2 of @react-navigation/native and version 5.2.16 @react-navigation/material-top-tabs, on React Native v0.61.5. Appreciate any insight anyone can provide — I just don't see where else there's room for an error here. Please let me know if you need any other information. Thanks for your time!


Solution

  • Update: the solution was ultimately to update the version of react-native-tab-view, which @react-navigation/material-top-tabs is dependent upon. With the latest react-native-tab-view version, 2.15.1, and version 5.2.16 of @react-navigation/material-top-tabs, my navigator is working as expected.