You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native Paper Menu组件报错:Cannot read property 'level2' of undefined

解决React Native Paper Menu组件"Cannot read property 'level2' of undefined"错误

问题场景

尝试在React Native项目的导航头部右侧添加React Native Paper的Menu组件,直接复制官方示例代码后运行,出现TypeError: Cannot read property 'level2' of undefined错误。

原代码

App.js

import { MD3LightTheme as DefaultTheme,PaperProvider } from 'react-native-paper';
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import HomeScreen from './screens/Home/index';
import RegisterScreen from './screens/Register/index';
import ForgotPasswordScreen from './screens/ForgotPassword';
import SetPasswordScreen from './screens/SetPassword';
import DashboardScreen from './screens/Dashboard';
import HeaderMenu from './components/HeaderMenu';

const Stack = createNativeStackNavigator();

const theme = {
  ...DefaultTheme,
  // Specify custom property
  myOwnProperty: true,
    ...DefaultTheme.colors,
  // Specify custom property in nested object
  colors: {
    error: '#B22D1D',
    primary: '#0a4b7c',
    success: '#357a38'
  },
};

const headerMenuOptions = {
  headerRight: () => ( <HeaderMenu /> )}

export default function App() {
  return (
    <PaperProvider theme={theme}>
    <NavigationContainer>
      <Stack.Navigator initialRouteName="Home">
        <Stack.Screen name="Home" options={{headerShown:false}} component={HomeScreen} />
        <Stack.Screen name="Register" component={RegisterScreen} />
        <Stack.Screen name="ForgotPassword" component={ForgotPasswordScreen} />
        <Stack.Screen name="SetPassword" component={SetPasswordScreen} />
        <Stack.Screen name="Dashboard" options={headerMenuOptions}  component={DashboardScreen} />
      </Stack.Navigator>
    </NavigationContainer>
    </PaperProvider>
  );
}

HeaderMenu.js

import * as React from "react";
import { View } from "react-native";
import { Button, Menu, Divider, PaperProvider } from "react-native-paper";

function HeaderMenu() {
const [visible, setVisible] = React.useState(true);

const openMenu = () => setVisible(true);

const closeMenu = () => setVisible(false);

return (
    <View
    style={{
    
    }}
    >
    <Menu
        visible={visible}
        onDismiss={closeMenu}
        anchor={<Button onPress={openMenu}>Show menu</Button>}
    >
        <Menu.Item onPress={() => {}} title="Item 1" />
        <Menu.Item onPress={() => {}} title="Item 2" />
        <Divider />
        <Menu.Item onPress={() => {}} title="Item 3" />
    </Menu>
    </View>
);
};

export default HeaderMenu;

错误信息

ERROR  TypeError: Cannot read property 'level2' of undefined

This error is located at:
    in Menu
    in ThemedComponent (created by withTheme(Menu))
    in withTheme(Menu) (created by HeaderMenu)
    in RCTView (created by View)
    in View (created by HeaderMenu)
    in HeaderMenu (created by HeaderConfig)
    in RNSScreenStackHeaderSubview (created by ScreenStackHeaderRightView)
    in ScreenStackHeaderRightView (created by HeaderConfig)
    in RNSScreenStackHeaderConfig (created by HeaderConfig)
    in HeaderConfig (created by SceneView)
    in RNSScreen
    in Unknown (created by InnerScreen)
    in Suspender (created by Freeze)
    in Suspense (created by Freeze)
    in Freeze (created by DelayedFreeze)
    in DelayedFreeze (created by InnerScreen)
    in InnerScreen (created by Screen)
    in Screen (created by SceneView)
    in SceneView (created by NativeStackViewInner)
    in Suspender (created by Freeze)
    in Suspense (created by Freeze)
    in Freeze (created by DelayedFreeze)
    in DelayedFreeze (created by ScreenStack)
    in RNSScreenStack (created by ScreenStack)
    in ScreenStack (created by NativeStackViewInner)
    in NativeStackViewInner (created by NativeStackView)
    in RCTView (created by View)
    in View (created by SafeAreaInsetsContext)
    in SafeAreaProviderCompat (created by NativeStackView)
    in NativeStackView (created by NativeStackNavigator)
    in PreventRemoveProvider (created by NavigationContent)
    in NavigationContent
    in Unknown (created by NativeStackNavigator)
    in NativeStackNavigator (created by App)
    in EnsureSingleNavigator
    in BaseNavigationContainer
    in ThemeProvider
    in NavigationContainerInner (created by App)
    in ThemeProvider (created by PaperProvider)
    in RCTView (created by View)
    in View (created by Portal.Host)
    in Portal.Host (created by PaperProvider)
    in RNCSafeAreaProvider (created by SafeAreaProvider)
    in SafeAreaProvider (created by SafeAreaInsetsContext)
    in SafeAreaProviderCompat (created by PaperProvider)
    in PaperProvider (created by App)
    in App (created by withDevTools(App))
    in withDevTools(App)
    in RCTView (created by View)
    in View (created by AppContainer)
    in RCTView (created by View)
    in View (created by AppContainer)
    in AppContainer
    in main(RootComponent), js engine: hermes
WARN  Possible Unhandled Promise Rejection (id: 7):
TypeError: Cannot read property 'level2' of undefined
TypeError: Cannot read property 'level2' of undefined

解决方案

1. 修复自定义主题结构

原主题代码错误地将DefaultTheme.colors展开到了主题的根层级,破坏了React Native Paper主题的原有结构,导致Menu组件无法读取到所需的level2样式属性。修改主题定义:

const theme = {
  ...DefaultTheme,
  myOwnProperty: true,
  colors: {
    ...DefaultTheme.colors, // 保留默认颜色,再覆盖自定义颜色
    error: '#B22D1D',
    primary: '#0a4b7c',
    success: '#357a38'
  },
};

2. 移除HeaderMenu中多余的PaperProvider导入

顶层App.js已经用PaperProvider包裹了整个应用,子组件中无需重复导入和使用PaperProvider,否则会导致主题上下文冲突。修改HeaderMenu.js的导入部分:

import * as React from "react";
import { View } from "react-native";
import { Button, Menu, Divider } from "react-native-paper"; // 移除PaperProvider

3. 调整Menu初始可见状态

默认将Menu的visible设为false,符合菜单默认隐藏的交互逻辑:

const [visible, setVisible] = React.useState(false);

修改后的完整代码

修改后的App.js

import { MD3LightTheme as DefaultTheme,PaperProvider } from 'react-native-paper';
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import HomeScreen from './screens/Home/index';
import RegisterScreen from './screens/Register/index';
import ForgotPasswordScreen from './screens/ForgotPassword';
import SetPasswordScreen from './screens/SetPassword';
import DashboardScreen from './screens/Dashboard';
import HeaderMenu from './components/HeaderMenu';

const Stack = createNativeStackNavigator();

const theme = {
  ...DefaultTheme,
  myOwnProperty: true,
  colors: {
    ...DefaultTheme.colors,
    error: '#B22D1D',
    primary: '#0a4b7c',
    success: '#357a38'
  },
};

const headerMenuOptions = {
  headerRight: () => ( <HeaderMenu /> )
}

export default function App() {
  return (
    <PaperProvider theme={theme}>
      <NavigationContainer>
        <Stack.Navigator initialRouteName="Home">
          <Stack.Screen name="Home" options={{headerShown:false}} component={HomeScreen} />
          <Stack.Screen name="Register" component={RegisterScreen} />
          <Stack.Screen name="ForgotPassword" component={ForgotPasswordScreen} />
          <Stack.Screen name="SetPassword" component={SetPasswordScreen} />
          <Stack.Screen name="Dashboard" options={headerMenuOptions}  component={DashboardScreen} />
        </Stack.Navigator>
      </NavigationContainer>
    </PaperProvider>
  );
}

修改后的HeaderMenu.js

import * as React from "react";
import { View } from "react-native";
import { Button, Menu, Divider } from "react-native-paper";

function HeaderMenu() {
  const [visible, setVisible] = React.useState(false);

  const openMenu = () => setVisible(true);
  const closeMenu = () => setVisible(false);

  return (
    <View>
      <Menu
        visible={visible}
        onDismiss={closeMenu}
        anchor={<Button onPress={openMenu}>Show menu</Button>}
      >
        <Menu.Item onPress={() => {}} title="Item 1" />
        <Menu.Item onPress={() => {}} title="Item 2" />
        <Divider />
        <Menu.Item onPress={() => {}} title="Item 3" />
      </Menu>
    </View>
  );
};

export default HeaderMenu;

修复原理

  • 主题结构错误是核心问题:React Native Paper的组件依赖主题中特定层级的样式定义,原代码破坏了主题结构,导致Menu组件无法读取level2属性。
  • 重复的PaperProvider会干扰主题上下文传递,导致子组件无法正确获取顶层主题。
  • 初始可见状态设为false符合常规菜单交互逻辑,避免组件加载时意外显示菜单。

内容的提问来源于stack exchange,提问作者Alaksandar Jesus Gene

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 02:07:03