首页 > 解决方案 > 如何为反应导航器创建包装子组件

问题描述

Tab.Navigator 组件只能有 Tab.Screen 组件作为直接子组件。

在 Typescript 中,有没有办法将 Tab.Screen Type 转换为 TabButton 函数?

const App = () => {
return (
    <NavigationContainer>
      <Tab.Navigator tabBarOptions={{
        ...>
        <Tab.Screen name={'name1'} component={component1} />
        <Tab.Screen name={'Add Photos'} component={FeedScreen}
                    options={{
                      tabBarButton: ...
        />
        <TabButton title={'Setting'} component={SettingScreen} imageSrc={'./icons/accountDark.png'}/>

}

这是我想要做的

type TabButtonProps = {
  title: string,
  component: any,
  imageSrc: string,
}
const TabButton = ({title, component, imageSrc}: TabButtonProps) => {
  return (
    <Tab.Screen name={title} component={component} options={{
      tabBarIcon: ({focused}) => (
        <View style={{alignItems: 'center', justifyContent: 'center', top: 10}}>
          <Image source={imageSrc as ImageSourcePropType}
                 resizeMode='contain'
                 style={{width: 25, height: 25, tintColor: focused ? '#999999' : '#dddddd'}}
          />
        </View>
      )}}/>
  )
}

我有什么:

Error: A navigator can only contain 'Screen' components as its direct children (found 'TabButton'). To render this component in the navigator, pass it in the 'component' prop to 'Screen'.

标签: typescriptreact-native

解决方案


这与 TypeScript 无关,因此强制转换无法解决此问题。您可以使用组件生成而不是包装组件:

const createTabButton = ({title, component, imageSrc}: TabButtonProps) => {
  return (
    <Tab.Screen name={title} component={component} options={{
      tabBarIcon: ({focused}) => (
        <View style={{alignItems: 'center', justifyContent: 'center', top: 10}}>
          <Image source={imageSrc as ImageSourcePropType}
                 resizeMode='contain'
                 style={{width: 25, height: 25, tintColor: focused ? '#999999' : '#dddddd'}}
          />
        </View>
      )}}/>
  )
}

...

const App = () => {
return (
    <NavigationContainer>
      <Tab.Navigator tabBarOptions={{
        ...>
        <Tab.Screen name={'name1'} component={component1} />
        <Tab.Screen name={'Add Photos'} component={FeedScreen}
                    options={{
                      tabBarButton: ...
        />
        {createTabButton({title: 'Setting', component: SettingScreen,  imageSrc:'./icons/accountDark.png'})}
    <NavigationContainer/>
}

您还可以通过设置显示名称来“欺骗”库:

TabButton.displayName = 'Tab.Screen'

推荐阅读