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

React Native使用BottomTab.Navigator与react-native-paper触发key属性警告

解决React Native中BottomNavigation.Bar的key属性展开警告

警告信息

警告:包含"key"属性的props对象正在被展开到JSX中:
<Touchable {...props} />
React的key必须直接传递给JSX,不能通过展开方式传递。

底部标签导航实现代码

function AppNav({ routes }) {
  const renderTabBar = ({ navigation, state, descriptors, insets }) => {
    const navigationBarProps = {
      version: 3,
      style: {
        backgroundColor: "#212529",
      },
      activeColor: "orange",
      inactiveColor: "lightgrey",
      shifting: false,
      navigationState: state,
      safeAreaInsets: insets,
      onTabPress: ({ route, preventDefault }) => {
        const event = navigation.emit({
          type: "tabPress",
          target: route.key,
          canPreventDefault: true,
        });

        if (event.defaultPrevented) {
          preventDefault();
        } else {
          navigation.dispatch({
            ...CommonActions.navigate(route.name, route.params),
            target: state.key,
          });
        }
      },
      renderIcon: ({ route, focused }) => {
        const { options } = descriptors[route.key];
        return options.tabBarIcon ? options.tabBarIcon({ focused, size: 24 }) : null;
      },
      getLabelText: ({ route }) => {
        const { options } = descriptors[route.key];
        return options.tabBarLabel ?? route.name;
      },
    };

    return <BottomNavigation.Bar {...navigationBarProps} />;
  };

  return (
    <BottomTab.Navigator
      screenOptions={{ headerShown: false }}
      tabBar={renderTabBar}
    >
      {routes?.map((route) => (
        <BottomTab.Screen
          key={route.key}
          name={route.name}
          component={route.component}
          options={{
            title: route.name,
            tabBarIcon: ({ size, focused }) => (
              <MaterialCommunityIcons
                name={focused ? route.icon_focused : route.icon_default}
                color={focused ? "orange" : "#fafafa"}
                size={size}
              />
            ),
          }}
        />
      ))}
    </BottomTab.Navigator>
  );
}

当前依赖版本

"react": "18.3.1",
    "react-native": "0.76.1",
    "expo": "^52.0.4",
    "@react-navigation/bottom-tabs": "^6.5.19",
    "@react-navigation/drawer": "^6.6.14",
    "@react-navigation/native": "^6.1.16",
    "@react-navigation/native-stack": "^6.9.25",

解决方案

1. 升级react-native-paper到兼容版本

你的依赖列表未标注react-native-paper版本,推测是版本过旧导致与React 18.3的key属性严格检查不兼容。执行以下命令升级到适配版本:

npm install react-native-paper@latest
# 或使用yarn
yarn add react-native-paper@latest

Expo 52(对应React Native 0.76.1)推荐使用react-native-paper@^5.12.0及以上版本,这类版本已修复与React 18.3的兼容性问题。

2. 显式传递props替代展开(备选方案)

如果升级后警告仍存在,可以放弃props展开,逐个显式传递BottomNavigation.Bar需要的属性,避免隐式传递可能包含key的未知props:

return (
  <BottomNavigation.Bar
    version={3}
    style={{ backgroundColor: "#212529" }}
    activeColor="orange"
    inactiveColor="lightgrey"
    shifting={false}
    navigationState={state}
    safeAreaInsets={insets}
    onTabPress={({ route, preventDefault }) => {
      const event = navigation.emit({
        type: "tabPress",
        target: route.key,
        canPreventDefault: true,
      });

      if (event.defaultPrevented) {
        preventDefault();
      } else {
        navigation.dispatch({
          ...CommonActions.navigate(route.name, route.params),
          target: state.key,
        });
      }
    }}
    renderIcon={({ route, focused }) => {
      const { options } = descriptors[route.key];
      return options.tabBarIcon ? options.tabBarIcon({ focused, size: 24 }) : null;
    }}
    getLabelText={({ route }) => {
      const { options } = descriptors[route.key];
      return options.tabBarLabel ?? route.name;
    }}
  />
);

3. 验证navigationState的结构

确保传递给navigationState的routes数组中,每个route对象的key属性唯一且合法,避免react-native-paper内部错误地将key作为props传递给子Touchable组件。


内容的提问来源于stack exchange,提问作者Brian

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 10:46:02