Как создать дочерний компонент-оболочку для react navigator

#typescript #react-native

Вопрос:

Компонент Tab.Navigator может иметь компонент Tab.Screen только в качестве прямого дочернего компонента.

В машинописном тексте есть ли способ преобразовать тип Tab.Screen в функцию 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'.
 

Ответ №1:

Речь идет не о машинописном тексте, поэтому кастинг не решит эту проблему. Вы можете использовать создание компонента вместо обернутого компонента:

 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'