Can you dynamically create screens within the React Navigation Tab Navigator using code?

My goal is to dynamically generate tabs in React-Navigation based on the values retrieved from an array, and pass the data from each array value to the corresponding screen. For instance, if there are 2 accounts, I expect 2 tabs with unique screens for each, and if there are 5 accounts, there should be 5 tabs with their respective screens generated based on the database values.

Here is what I have tried so far:

interface Account {
    accountNumber: string;
    balance: number;
}

const accounts: Account[] = [
    { accountNumber: '1', balance: 10 },
    { accountNumber: '2', balance: 15 },
    { accountNumber: '3', balance: 20 }
];


class AccountScreen extends React.Component<Account>{
    constructor(props: Account) {
      super(props)
    }

    render() {
        return (
          <View>
            <Text>This is an Account</Text>
            <Text>Account Number: {this.props.accountNumber}</Text>
            <Text>Balance: £{(this.props.balance/100).toFixed(2)}</Text>
          </View>
        );
    }
};

const accountScreens = {};

accounts.forEach(account => accountScreens[account.accountNumber] = { screen: AccountScreen, props: account }); 
// SOMETHING LIKE THIS

export default AccountNavigator = createMaterialTopTabNavigator(accountScreens);

While the screens display with the appropriate tabs, the data within each account is not being passed through props. I understand that props cannot be passed directly into the Navigator, but I am unsure of how to make that data accessible to the component. Is there a fundamental flaw in my approach, or is there a syntactic issue that I am overlooking?

Thank you for your assistance!


Solution:

I discovered that the props can be accessed by returning a function to the screen key in the navigator.

Here is the final solution that resolved the issue for me:

accounts.forEach(account => {
    accountScreens[account.accountNumber] = {screen: (props) => {
        return <AccountScreen accountNumber={account.accountNumber} {...props} />}
    }
})

Answer №1

Remember, I haven't actually checked this, but this is the general idea!

/*...your code*/

let screens = accounts.map(e=>{screen:(props)=><AccountScreen account={e} {...props}/>})

export default AccountNavigator = createMaterialTopTabNavigator({...screens});

Keep in mind: The screen names will correspond to the indexes of your objects in this code snippet. When you need to navigate, use navigation.navigate('1')

It's fine that you're generating screens during initialization. However, I suggest working with just one screen and making adjustments there!

Answer №2

Unfortunately, the current stable version of React Navigation does not have the capability to dynamically generate screens based on data.

However, React Navigation 5 introduces a new dynamic API that allows for this functionality. You can learn more about it here:

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

Showing the Enum name rather than the value in an Angular HTML template for a bound Typescript Interface

After retrieving an array of objects with various properties from a .NET Controller, I am utilizing the following Typescript code: import { Component, Inject } from '@angular/core'; import { HttpClient } from '@angular/common/http'; @Co ...

Utilizing NPM Workspace Project in conjunction with Vite to eliminate the necessity of the dist folder during the Vite build process

I am currently working on a project that involves a module using full path exports instead of index files. This project is divided into 2 NPM workspaces: one called core and the other called examples. The challenge I am facing is avoiding long import pat ...

Troubleshooting an angular problem with setting up a dynamic slideshow

I am currently working on building a slideshow using plain HTML, CSS, and JavaScript. I referred to the following example for guidance: https://www.w3schools.com/howto/tryit.asp?filename=tryhow_js_slideshow_auto However, despite implementing the code prov ...

Specify that a function is adhering to an interface

Is there a way in Typescript to ensure that a function implements a specific interface? For example: import { BrowserEvents, eventHandler, Event } from './browser-events'; export function setup(){ const browserEvents = new BrowserEvents(); b ...

What is the best way to save code snippets in Strapi for easy integration with SSG NextJS?

While I realize this may not be the typical scenario, please listen to my situation: I am using Strapi and creating components and collections. One of these collections needs to include code snippets (specifically typescript) that I have stored in a GitH ...

When implementing JSS with React and TypeScript, certain CSS properties may encounter a `type is unassignable` error

Recently delving into TypeScript, I've encountered an issue within my project that was created using create-react-app with TypeScript and incorporates JSS. It appears that certain CSS properties are causing errors. Specifically, the pointerEvents and ...

Encounter an Unexpected Token Issue when using NextJS-auth0 in Jest

I am facing a problem with my Next.js app that is integrated with the nextjs-auth0 package. Whenever I attempt to test a particular file and include the following import: import { getSession } from '@auth0/nextjs-auth0'; An error occurs, stating ...

Using Vue js and Typescript to automatically scroll to the bottom of a div whenever there are changes in

My goal is to automatically scroll to the bottom of a div whenever a new comment is added. Here's what I have been trying: gotoBottom() { let content = this.$refs.commentsWrapper; content.scrollTop = content.scrollHeight } The div containing ...

What is the best way to extract items from another array that have approved IDs - is it through using map(), filter(),

I am unsure about the best approach to retrieve only the items (array with objects) that have been approved based on their id. Should I start by using map() and then filter(), or should I filter() them first and then map()? export class AppComponent { ...

Using React Native to dynamically change color based on API response

I'm currently working on a React Native project and I have a requirement to dynamically change the background color of a styled component based on the value retrieved from an API. However, I'm facing some challenges in implementing this feature. ...

Tips for creating an interface in TypeScript that prevents access to uninitialized properties of a class

Interfaces still baffle me a bit. I understand that interfaces are typically used for public properties, but I want to create an interface that will prevent access to uninitialized properties. Currently, I am able to access this.material without any errors ...

Failure to update values in local storage using the React useLocalStorage hook

I've developed two unique custom hooks named useLocalStorage and useAuth. function getDefaultValue<T>(key: string, initialValue: T | null): T | null { const storedValue: string | null = localStorage.getItem(key); if (storedValue) { retur ...

Error: Unable to inject HttpClient dependency. Angular 5

I recently switched to using the Angular template in Visual Studio 2017 and decided to update to Angular 5.2. However, I encountered an error while trying to make a http call from the service class. The error message I received is: https://i.sstatic.net/p ...

The chart JS label callback requires a specified type declaration

Currently, I am in the process of updating an old Angular platform to a newer version. One requirement is that everything must have its type declaration. I encountered a problem with the label callback showing this error: The error message reads: "Type &a ...

Passing properties from the parent component to the child component in Vue3JS using TypeScript

Today marks my inaugural experience with VueJS, as we delve into a class project utilizing TypeScript. The task at hand is to transfer the attributes of the tabsData variable from the parent component (the view) to the child (the view component). Allow me ...

Develop a TypeScript class that includes only a single calculated attribute

Is it advisable to create a class solely for one computed property as a key in order to manage the JSON response? I am faced with an issue where I need to create a blog post. There are 3 variations to choose from: A) Blog Post EN B) Blog Post GER C) Bl ...

Why doesn't WebStorm display TypeScript inspection errors in real-time?

I'm currently utilizing WebStorm 2017.2.4 in conjunction with Angular 4.3 - I am facing an issue where TypeScript errors are not being displayed: https://i.sstatic.net/pcLQX.png Query How can I enable real-time inspections to occur immediately? (I ...

What is the best way to handle success data in React Query?

Currently, I have an API call function (using httpClient as axios instance) interface IRegisterResponse { accessToken: string; } export const register = async ({ name, password, token, }: IRegisterParams) => await httpClient.post<IRegiste ...

Guide to updating the canvas in Chart.js based on a user-defined x-axis range

What I currently have: My chart.js canvas displays values on the x-axis ranging from 1 to 9. Users can input a new range to view a different scope, with default limits set at start = 3 and end = 6 in my repository. I already have a function that restrict ...

Discover the latest DOM elements using Webdriverio 5

Currently, I am developing a REact based CMS application that features a form with multiple carousels. I am encountering an issue where the webdriverio implementation is unable to locate an element, even though the same xpath works fine when tested manua ...