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

React Native自定义BottomTabCard组件props与navigation传递报错解决

React Native自定义BottomTabCard组件报错及导航问题解决

问题背景

我在React Native中开发了自定义BottomTabCard函数式组件,代码如下:

const BottomTabCard=({props,navigation})=> {
  const [isActive, setIsActive] = useState('');
  return (
    <View
      style={[
        styles.container,
        {height: props.TabHeight, width: props.TabWidth},
      ]}>
      <View style={{flexDirection: 'row'}}>
        <TouchableOpacity onPress={() => setIsActive('home')}>
          <Icons
            name="home"
            size={35}
            style={[
              styles.iconHome,
              {color: isActive == 'home' ? 'green' : 'grey'},
            ]}
          />
        </TouchableOpacity>
        <TouchableOpacity onPress={() => setIsActive('shopping-cart')}>
          <Icons
            name="shopping-cart"
            size={35}
            style={[
              styles.iconCart,
              {color: isActive == 'shopping-cart' ? 'green' : 'grey'},
            ]}
          />
        </TouchableOpacity>
        <TouchableOpacity onPress={() => setIsActive('search')}>
          <Icons
            name="search"
            size={35}
            style={[
              styles.iconSearch,
              {color: isActive == 'search' ? 'green' : 'grey'},
            ]}
          />
        </TouchableOpacity>
        <TouchableOpacity onPress={() => setIsActive('person')}>
          <Icons
            name="person"
            size={35}
            style={[
              styles.iconPerson,
              {color: isActive == 'person' ? 'green' : 'grey'},
            ]}
          />
        </TouchableOpacity>
        <TouchableOpacity onPress={() => setIsActive('credit-card'),{navigation.navigate(ROUTE_NAME.ORDER)}}>
          <Icons
            name="credit-card"
            size={35}
            style={[
              styles.iconCard,
              {color: isActive == 'credit-card' ? 'green' : 'grey'},
            ]}
          />
        </TouchableOpacity>
      </View>
    </View>
  );
}

export default BottomTabCard;

我希望点击credit-card图标时跳转到对应页面,但出现了报错,该组件在Login页面中被使用,Login页面包含其他卡片组件。

报错信息

TypeError: Cannot read property 'TabHeight' of undefined

错误栈信息:

This error is located at:
    in BottomTabCard (created by Login)
    in RCTView (created by View)
    in View (created by Login)
    in Login (created by SceneView)
    in StaticContainer
    in EnsureSingleNavigator (created by SceneView)
    in SceneView (created by SceneView)
    in RCTView (created by View)
    in View (created by DebugContainer)
    in DebugContainer (created by MaybeNestedStack)
    in MaybeNestedStack (created by SceneView)
    in RCTView (created by View)
    in View (created by SceneView)
    in RNSScreen (created by AnimatedComponent)
    in AnimatedComponent
    in AnimatedComponentWrapper (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 RNCSafeAreaProvider (created by SafeAreaProvider)
    in SafeAreaProvider (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 MyStack)
    in MyStack (created by Route)
    in EnsureSingleNavigator
    in BaseNavigationContainer
    in ThemeProvider
    in NavigationContainerInner (created by Route)
    in Route (created by App)
    in Provider (created by App)
    in App
    in RCTView (created by View)
    in View (created by AppContainer)
    in RCTView (created by View)
    in View (created by AppContainer)
    in AppContainer
    in behalal(RootComponent), js engine: hermes

疑问

  • 是否可以在函数式组件中同时接收props和navigation?
  • 如何解决上述报错?

解决方案

1. 关于函数式组件接收props和navigation的问题

当然可以同时接收,只是你的参数解构写法错误。React组件的参数本身就是props对象,navigation是父组件(比如Login页面)传入的其中一个属性,你需要正确解构这些属性。

2. 核心报错修复(参数解构错误)

原组件定义const BottomTabCard=({props,navigation})=>是错误的:

  • 这种写法意味着你想从props对象里解构出名为props和navigation的属性,但父组件实际传入的是TabHeight、TabWidth和navigation,并没有名为props的属性,导致props变量为undefined,访问props.TabHeight就会抛出错误。

修复方式二选一:

  • 方式一:直接解构需要的属性
const BottomTabCard=({ TabHeight, TabWidth, navigation })=> {
  const [isActive, setIsActive] = useState('');
  return (
    <View
      style={[
        styles.container,
        {height: TabHeight, width: TabWidth}, // 直接使用解构后的变量
      ]}>
      {/* 其他代码不变 */}
    </View>
  );
}
  • 方式二:用props接收所有属性,再单独提取navigation
const BottomTabCard=(props)=> {
  const { navigation } = props;
  const [isActive, setIsActive] = useState('');
  return (
    <View
      style={[
        styles.container,
        {height: props.TabHeight, width: props.TabWidth}, // 用props访问属性
      ]}>
      {/* 其他代码不变 */}
    </View>
  );
}

3. 导航点击事件修复

原代码中credit-card的点击事件语法错误:

// 错误写法:逗号运算符不能正确执行多个语句
onPress={() => setIsActive('credit-card'),{navigation.navigate(ROUTE_NAME.ORDER)}}

正确写法:用大括号包裹多个语句,按顺序执行:

<TouchableOpacity onPress={() => {
  setIsActive('credit-card');
  navigation.navigate(ROUTE_NAME.ORDER);
}}>
  {/* Icon代码不变 */}
</TouchableOpacity>

4. 可选优化:简化重复代码

可以把所有tab项抽成数组,通过map渲染,减少冗余代码:

const BottomTabCard=({ TabHeight, TabWidth, navigation })=> {
  const [isActive, setIsActive] = useState('');
  
  // 定义tab项数组
  const tabItems = [
    { key: 'home', iconName: 'home', styleKey: 'iconHome' },
    { key: 'shopping-cart', iconName: 'shopping-cart', styleKey: 'iconCart' },
    { key: 'search', iconName: 'search', styleKey: 'iconSearch' },
    { key: 'person', iconName: 'person', styleKey: 'iconPerson' },
    { key: 'credit-card', iconName: 'credit-card', styleKey: 'iconCard', route: ROUTE_NAME.ORDER },
  ];

  return (
    <View
      style={[
        styles.container,
        {height: TabHeight, width: TabWidth},
      ]}>
      <View style={{flexDirection: 'row'}}>
        {tabItems.map(item => (
          <TouchableOpacity
            key={item.key}
            onPress={() => {
              setIsActive(item.key);
              // 如果有路由则跳转
              if (item.route) {
                navigation.navigate(item.route);
              }
            }}
          >
            <Icons
              name={item.iconName}
              size={35}
              style={[
                styles[item.styleKey],
                {color: isActive === item.key ? 'green' : 'grey'},
              ]}
            />
          </TouchableOpacity>
        ))}
      </View>
    </View>
  );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 04:15:32