React Native中NavigationContainer主题箭头函数报错排查
我尝试将NavigationContainer的theme属性从三元表达式:
<NavigationContainer theme={theme == 'Amber' ? Amber : Tiger}>
改为箭头函数形式:
<NavigationContainer theme={() => { if (theme == 'Amber') { return Amber; } else { return Tiger; } }}>
修改后出现错误:TypeError: undefined is not an object (evaluating 'colors.background')
问题原因
NavigationContainer的theme属性要求直接传入主题对象,而不是函数。你现在传递的是一个箭头函数,导航组件会尝试读取这个函数的colors.background属性,但函数本身并没有该属性,因此触发了undefined报错。
解决方法
方法1:使用条件表达式或提前计算主题变量(推荐)
把主题判断逻辑提前提取为组件内的变量,再传递给theme属性:
export default function MainContainer() { const [theme, setTheme] = useState('Amber'); // 提前计算选中的主题 const selectedTheme = theme === 'Amber' ? Amber : Tiger; const themeData = { theme, setTheme }; return ( <ThemeContext.Provider value={themeData}> {/* 直接传入主题对象 */} <NavigationContainer theme={selectedTheme}> {/* 其余代码不变 */} </NavigationContainer> </ThemeContext.Provider> ); }
方法2:立即执行箭头函数(不推荐,可读性差)
如果一定要用函数形式,需要立即调用函数返回主题对象,而不是传递函数本身:
<NavigationContainer theme={(() => { if (theme == 'Amber') { return Amber; } else { return Tiger; } })()}>
完整修正代码示例
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 selectedTheme = theme === 'Amber' ? Amber : Tiger; const themeData = { theme, setTheme }; return ( <ThemeContext.Provider value={themeData}> <NavigationContainer theme={selectedTheme}> <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> ); }
内容的提问来源于stack exchange,提问作者Hypo
相关产品推荐
相关产品推荐

