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');