Element type is invalid: expected a string (for built-in components) or a class/function

I am getting the following error in my react-native app. It works fine when debugging in chrome (npm run web) but when I generate apk it crashes on start.

It’s apparently a common problem and already asked multiple time(1, 2, 3) but none of these helped me.

I can’t post the whole app here because I don’t know which file causes the problem but this is the index component.

import React, { useState, useEffect, useRef } from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import * as Device from 'expo-device';
import * as Notifications from 'expo-notifications';
import { Platform } from 'react-native';
import { configureStore } from '@reduxjs/toolkit';
import { Provider } from 'react-redux';

import Home from './components/home';
import About from './components/about';
import { isWeb } from './utilities';

import rootReducer from './reducers';
import { setPushNotificationToken } from './services/identityService';

const Stack = createNativeStackNavigator();
const store = configureStore({
  reducer: rootReducer,
});

Notifications.setNotificationHandler({
  handleNotification: async () => ({
    shouldShowAlert: true,
    shouldPlaySound: false,
    shouldSetBadge: false,
  }),
});

async function registerForPushNotificationsAsync() {
  let token;
  if (Device.isDevice) {
    const { status: existingStatus } = await Notifications.getPermissionsAsync();
    let finalStatus = existingStatus;
    if (existingStatus !== 'granted') {
      const { status } = await Notifications.requestPermissionsAsync();
      finalStatus = status;
    }
    if (finalStatus !== 'granted') {
      if (!isWeb) {
        alert('Failed to get push token for push notification!');
      }
      return '<error>';
    }
    token = (await Notifications.getExpoPushTokenAsync()).data;
  } else {
    alert('Must use physical device for Push Notifications');
  }

  if (Platform.OS === 'android') {
    await Notifications.setNotificationChannelAsync('default', {
      name: 'default',
      importance: Notifications.AndroidImportance.MAX,
      vibrationPattern: [0, 250, 250, 250],
      lightColor: '#FF231F7C',
    });
  }

  return token;
}

export default function Index() {
  const [, setNotification] = useState(false);
  const notificationListener = useRef();
  const responseListener = useRef();

  useEffect(() => {
    registerForPushNotificationsAsync().then((token) => {
      store.dispatch(setPushNotificationToken(token));
      // TODO: call backend to register the device token
    });

    notificationListener.current = Notifications.addNotificationReceivedListener((notification) => {
      setNotification(notification);
    });

    responseListener.current = Notifications.addNotificationResponseReceivedListener(() => {
      // TODO: call backend to notify notification was read
    });

    return () => {
      Notifications.removeNotificationSubscription(notificationListener.current);
      Notifications.removeNotificationSubscription(responseListener.current);
    };
  }, []);

  return (
    <Provider store={store}>
      <NavigationContainer>
        <Stack.Navigator initialRouteName="Home">
          <Stack.Screen
            name="Home"
            component={Home}
            options={{
              title: 'Overview',
            }}
          />
          <Stack.Screen name="About" component={About} />
        </Stack.Navigator>
      </NavigationContainer>
    </Provider>
  );
}

Error:

Exception com.facebook.react.common.JavascriptException: Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.
This error is located at:
    in Unknown
    in Unknown
    in Unknown
    in RCTView
    in Unknown
    in RCTView
    in Unknown
    in b, stack:
Ii@35:89340
<unknown>@35:40603
Fl@35:58157
xa@35:92676
vi@35:83678
gi@35:83606
hi@35:83371
oi@35:80340
oi@-1
xt@35:27446
ni@35:77138
ji@35:91646
<unknown>@35:97778
<unknown>@348:1279
run@339:1403
runApplication@339:2420
value@61:3579
<unknown>@61:758
value@61:2582
value@61:730
value@-1
  at com.facebook.react.modules.core.ExceptionsManagerModule.reportException (ExceptionsManagerModule.java:72)
  at java.lang.reflect.Method.invoke
  at com.facebook.react.bridge.JavaMethodWrapper.invoke (JavaMethodWrapper.java:372)
  at com.facebook.react.bridge.JavaModuleWrapper.invoke (JavaModuleWrapper.java:188)
  at com.facebook.react.bridge.queue.NativeRunnable.run
  at android.os.Handler.handleCallback (Handler.java:938)
  at android.os.Handler.dispatchMessage (Handler.java:99)
  at com.facebook.react.bridge.queue.MessageQueueThreadHandler.dispatchMessage (MessageQueueThreadHandler.java:27)
  at android.os.Looper.loopOnce (Looper.java:201)
  at android.os.Looper.loop (Looper.java:288)
  at com.facebook.react.bridge.queue.MessageQueueThreadImpl$4.run (MessageQueueThreadImpl.java:228)
  at java.lang.Thread.run (Thread.java:920)

Repository

Play Store

Hi @amir734jj

When you debug in Chrome your code is running in Chrome’s JavaScript engine as opposed to JavaScript Code or Hermes, so there can be some differences in behaviour as a result.

Since you don’t know where in the code the problem is, the easiest way to track it down is probably with git bisect. Assuming an older commit works for you and the latest commit fails but you do not know which commit introduced the change, you can use git bisect to help track down the bad commit. Once you have the commit, you can check the diff carefully for anything that might have caused this.

Alternatively you can try commenting out half your app to see if it still crashes in the same way. If so, the problem is in the other half. If it no longer crashes, the problem is probably in the part you commented out. You can narrow it down by commenting out/uncommenting different parts of your app. You could also approach it from the other side. Create a new app and start copying parts of your code from the real app into the new app. At some point you’ll presumably start getting the error in the new app. If so, you know that the error is coming from the part that you just copied.

Good luck