Step-by-step guide on building a wrapper child component for a React navigator

When using the Tab.Navigator component, it is important to note that only the Tab.Screen component can be a direct child component.

Is there a way in Typescript to convert or cast the Tab.Screen Type to the TabButton function?

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'}/>

}

This is what I am attempting to achieve:

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>
      )}}/>
  )
}

Current issue:

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'.

Answer №1

When it comes to TypeScript, using casting won't be the solution. One alternative approach is to create a component instead of wrapping it:

const generateTabButton = ({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: ...
        />;
        {generateTabButton({title: 'Setting', component: SettingScreen,  imageSrc:'./icons/accountDark.png'})}
    <NavigationContainer/>
}

Another potential workaround could involve setting the display name in a creative way:

TabButton.displayName = 'Tab.Screen'

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

I am facing difficulty in retrieving data from Firestore using Angular

I've been utilizing the AngularFireList provided by @angular/fire/database to retrieve data from firestore. However, despite having data in the firestore, I am unable to fetch any information from it. import { Injectable } from '@angular/core&apo ...

Breaking down a large GraphQL request into multiple smaller requests

Having encountered an issue with my request body becoming too large when using the Apollo React Native client, I am exploring options to split this request into smaller chunks. Specifically, I am interested in determining if parallelization is feasible. T ...

A step-by-step guide on injecting dependencies manually in NestJS

When working with Angular, it is possible to access and inject dependencies manually using the built-in Injector class. This allows you to access and inject services without having to pass them through the constructor. Essentially, you can inject a service ...

Combine two comma-separated strings in JavaScript to create an array of objects

I have two strings separated by commas that I want to transform into an array of objects. { "id": "1,2,3", "name": "test 1, test 2, test 3" } Is there a way to convert this into the desired object format? { &q ...

The canActivate function must be responsive to the true or false value of this.authService.isLoggedIn before proceeding

I am facing a problem with my app's routing functionality. When the user logs in with their Google email, I want the app to route to the home page: "". Everything seems to work fine except for the canActivate routeGuard. During the AuthLogin ...

Is there a way to change a .pptx document into a base64 string?

Currently, I am working on a project that involves creating an addin for Office. The challenge I am facing is opening other pptx files from within the addin. After some research, I discovered that I need to use base64 for the PowerPoint.createPresentation( ...

What is the process for defining a default value for a template-driven form input in Angular 2?

I have a simple input element in my form that requires a default initial value to be set. <input type="number" name="interest_rate" [(ngModel)]="interest_rate"> In my code, I included this.form.controls['interest_rate'].patchValue(this.a ...

Installing a React Native app onto a wireless router is a straightforward process that can greatly

I need assistance with installing a React Native application on a WIRELESS LAN CONTROLLER system similar to a captive portal. Query: What is the process for installing my application on this router? Is it feasible to install my application on that route ...

Leveraging AnimatePresence from the Framer Motion library to design an exit animation for a motion.div

My goal is to implement a side menu that smoothly slides in and out when the menu/close button is clicked using framer motion. Initially, clicking on the menu button will cause the menu to slide out from the left side of the screen while changing the butto ...

I encountered a SyntaxError while parsing JSON due to an absence of a number after a minus sign at position 1

I am trying to use the replicate model visoar/product-photo:edf42659dae0da88a26dba4912e7e4bb6c2fba25b1e1c6a5464cf220e467bce0, but when I provide it with an image and a prompt like on this page.tsx: "use client" import { LandingNavBar } from &apo ...

disable the react .hover behavior once clicked

Can someone help me figure out why my attempt to cancel the .hover on function using .off is not working? $("document").ready(function(){ $("button").hover(function(){ $("h1").hide(); }, function(){ ...

Locate and retrieve the item that appears most often in a given array

In order to determine the mode of an array consisting of integer numbers only, I must create a function named findMode. If the array is empty, the function should return 0. Otherwise, it should return the element that occurs most frequently in the array. I ...

Can we specify a more specific type for an argument in Typescript based on another argument in a function?

I'm in the process of developing a compact DSL for filter operations and crafting helper methods to support it. Suppose I have a function const equals = (left, right) => {} This function needs to be typed so that the left value is a field within ...

Guide on incorporating arrow buttons for navigation on the left and right sides within a Primeng tab view component in Angular 8

Looking to enhance navigation tabs with left and right arrows for better support of larger tab sizes in the nav menu. I attempted using Primeng since my Angular 8 application already utilizes this library. Are there any other libraries besides Angular Ma ...

Error in Angular 4: Undefined property 'replace' causing trouble

I've been trying to use the .replace() JavaScript function in Angular 4 to remove certain characters from a string. Here is the code snippet from my component: @Component({...}) export class SomeComponent implements OnInit { routerUrl: string = &apo ...

Is it possible to deduce the output type of a function based on its input?

In a web development project, the function getFormData() plays a crucial role in validating and sanitising a FormData object based on a specified schema. If the validation process goes smoothly without any errors, the function will return the cleansed Form ...

Having Trouble Importing a Dependency in TypeScript

My experience with using node js and typescript is limited. I attempted to include the Paytm dependency by executing the following code: npm install paytmchecksum or by inserting the following code in package.json "dependencies": { ... & ...

Encountering an error in React Native while trying to use a custom component I created, receiving the following message: "Error: undefined Unable to resolve module <MyModule>"

I have developed a unique custom component named "react-native-weekly-calendar" with the intention of sharing it with the open source community. However, before I proceed with publishing it, I wanted to conduct some testing. Unfortunately, when attempting ...

"Exploring the world of Typescript declarations and the CommonJS module

I'm encountering confusion while creating declaration files (d.ts). For instance, I have developed an NPM package called "a" with a single CommonJS module index.ts: export interface IPoint { x: number; y: number; } export default function s ...

Ways to trigger the keyup function on a textbox for each dynamically generated form in Angular8

When dynamically generating a form, I bind the calculateBCT function to a textbox like this: <input matInput type="text" (keyup)="calculateBCT($event)" formControlName="avgBCT">, and display the result in another textbox ...