Home > Back-end >  React Native "undefined is not an object" arrow function
React Native "undefined is not an object" arrow function

Time:11-12

I'm trying to switch this line of code to an arrow function:

<NavigationContainer theme={theme == 'Amber' ? Amber : Tiger}

            <NavigationContainer theme={() => {
                if (theme == 'Amber') {
                    return Amber;
                } else {
                    return Tiger;
                }
            }}>

But for some reason when I perform this change, I get this error: TypeError: undefined is not an object (evaluating 'colors.background')

What's the problem here? Thanks

Full code for reference:

import React, { useState } from 'react';

import { NavigationContainer, useTheme } from '@react-navigation/native';
import { StatusBar } from 'expo-status-bar';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import * as NavigationBar from "expo-navigation-bar";
import Ionicons from 'react-native-vector-icons/Ionicons';

import CounterScreen from './screens/CounterScreen';
import CustomizeScreen from './screens/CustomizeScreen';
import SettingsScreen from './screens/SettingsScreen';
import MedalsScreen from './screens/MedalsScreen.js';

import { Amber, Tiger } from "../styles/Themes"
import { ThemeContext } from '@rneui/themed';

const counterName = 'Counter';
const customizeName = 'Customize';
const settingsName = 'Settings';
const medalsName = "Medals";

const Tab = createBottomTabNavigator();
NavigationBar.setBackgroundColorAsync("#212121");

export default function MainContainer() {

    const [theme, setTheme] = useState('Amber');

    const themeData = { theme, setTheme };

    return (

        <ThemeContext.Provider value={themeData}>
            <NavigationContainer theme={() => {
                if (theme == 'Amber') {
                    return Amber;
                } else {
                    return Tiger;
                }
            }}>

                <StatusBar style="auto" />

                <Tab.Navigator
                    initialRouteName={counterName}
                    screenOptions={({ route }) => ({
                        tabBarIcon: ({ focused, color, size }) => {
                            let iconName;
                            let rn = route.name;

                            if (rn === counterName) {
                                iconName = focused ? 'radio-button-on-outline' : 'radio-button-off-outline';
                            } else if (rn === customizeName) {
                                iconName = focused ? 'color-palette' : 'color-palette-outline';
                            } else if (rn === medalsName) {
                                iconName = focused ? 'medal' : 'medal-outline';
                            } else if (rn === settingsName) {
                                iconName = focused ? 'settings' : 'settings-outline';
                            }

                            return <Ionicons name={iconName} size={size} color={color} />

                        },
                        tabBarInactiveTintColor: '#aaaaaa',
                        tabBarLabelStyle: { paddingBottom: 10, fontSize: 10 },
                        tabBarStyle: { padding: 10, height: 70, borderTopWidth: 1 },

                        headerStyle: { borderBottomWidth: 1 },
                        headerTitleAlign: 'center',
                        headerTitleStyle: { fontSize: 20 },
                    })}>

                    <Tab.Screen name={counterName} component={CounterScreen} />
                    <Tab.Screen name={customizeName} component={CustomizeScreen} />
                    <Tab.Screen name={medalsName} component={MedalsScreen} />
                    <Tab.Screen name={settingsName} component={SettingsScreen} />

                </Tab.Navigator>

            </NavigationContainer>
        </ThemeContext.Provider>

    );
}

Themes.js

const Amber = {
    dark: true,
    colors: {
      primary: '#FFBF00',
      background: '#212121',
      card: '#212121',
      text: '#FFBF00',
      border: '#FFBF00',
      notification: '#FFBF00',
    },
  };

  const Tiger = {
    dark: true,
    colors: {
      primary: '#F96815',
      background: '#212121',
      card: '#212121',
      text: '#F96815',
      border: '#F96815',
      notification: '#F96815',
    },
  };

  export { Amber, Tiger }

CodePudding user response:

looks like its expecting an object, why not try using useMemo or a simple function the generated an object before setting the proprty

 const containerTheme = useMemo(() => {
   // logic to select theme
   if (theme == 'Amber') {
       return Amber;
    } else {
        return Tiger;
    }

 }, [theme])

 <NavigationContainer theme={containerTheme}>

  // simple function
   const getTheme = () => {
   // logic to select theme
   if (theme == 'Amber') {
       return Amber;
    } else {
        return Tiger;
    }
 }

 const containerTheme = getTheme();

if your function is expensive check the time

console.time('get theme');
const containerTheme = getTheme();
console.timeEnd('get theme');
  • Related