"Navigate to another screen with the FlatList component upon press, displaying specific

I've created a flatlist of countries with a search filter using an API. I need help implementing a feature where clicking on a country's name in the list redirects to a screen that displays the country's name and number of cases. The screen I want to display this information is called LocationDataScreen. Any assistance would be greatly appreciated :)

Below is my current code snippet:

const fetchData = () => {
    const apiURL = "https://coronavirus-19-api.herokuapp.com/countries";
    fetch(apiURL)
      .then((response) => response.json())
      .then((responseJson) => {
        setFilteredData(responseJson);
        setMasterData(responseJson);
      })
      .catch((error) => {
        console.error(error);
      });
  };

  const SearchFilter = (text) => {
    if (text) {
      const newData = filteredData.filter((item) => {
        const itemData = item.country;

        const textData = text.toUpperCase();
        return itemData.indexOf(textData) > -1;
      });
      setFilteredData(newData);
      setSearch(text);
    } else {
      setFilteredData(masterData);
      setSearch(text);
    }
  };

  const ItemView = ({ item }) => {
    
    return (
      <RectButton
        onPress={() => navigation.navigate("LocationDataScreen")}
        style={styles.searchcontainer}
      >
        <Text style={[styles.itemStyle, { textTransform: "capitalize" }]}>
          {item.id}
          {item.country.toUpperCase()}
        </Text>
      </RectButton>
    );
  };

  const ItemSeparatorView = () => {
    return (
      <View
        style={{
          height: 1.5,
          width: "90%",
          marginLeft: 35,
          backgroundColor: "#f3f2f8",
        }}
      />
    );
  };

  return (
    <ScrollView
      contentInsetAdjustmentBehavior="automatic"
      stickyHeaderIndices={[0]}
      style={[styles.container, { flex: 1 }]}
    >
      <SearchBarCustom
        value={search}
        placeholder="Search"
        containerStyle={{ backgroundColor: "#f3f2f8" }}
        inputContainerStyle={{
          backgroundColor: "#e3e3e9",
          height: 25,
          marginHorizontal: 5,

          marginTop: -5,
        }}
        placeholderTextColor="#96969b"
        platform="ios"
        onChangeText={(text) => SearchFilter(text)}
      />
      <FlatList
        data={filteredData}
        keyExtractor={(item, index) => index.toString()}
        ItemSeparatorComponent={ItemSeparatorView}
        renderItem={ItemView}
        style={styles.listcontainer}
      />
    </ScrollView>
  );
};

Answer №1

To send data to the LocationDataScreen.tsx, you need to pass it as props. Here's how:

Your onPress function should be like this:

onPress={() =>
  navigation.navigate('LocationDataScreen', { ...item })
}

To access the passed data, you can use the following code in your lifecycle functions (e.g., componentDidMount()):

this.props.navigation.state.params

You can also save the data directly in the state of your screen LocationDataScreen.tsx. When using a Class component, your code will look like this:

import * as React from 'react';
import { Text, View, StyleSheet } from 'react-native';

interface Props {
  navigation: any
}

interface State {
  population: Int16Array;
  name: String
}

class LocationDataScreen extends React.Component<Props, State> {
  constructor(props:Props){
  super(props);
  this.state= {
    ...props.navigation.state.params
  }
}

  render(){
    const {population, name} = this.state;
    return (
      <View>
        <Text>Country Name - {name}</Text>
        <Text>Country Population - {population}</Text>
      </View>
    );
  }
}

export default LocationDataScreen;

When using a Function component:

function LocationDataScreen({ route, navigation }) {
  const { country, cases } = route.params

  return (
    <View style={styles.container}>
      <Text>{country}</Text>
      <Text>{cases}</Text>
    </View>
  );
}

Your stack navigator setup should look like this:

const CountryRoute = createStackNavigator(
{
   CountryList: {
     screen: CountryList,
   },
   
   LocationDataScreen: {
     screen: LocationDataScreen, 
   },

},
{
initialRouteName: 'CountryList',
},
);

For StackNavigation, make sure you are using:

"react-navigation-stack": "^1.10.3",

That should cover it.

Answer №2

Feel free to take a look at this Snack I put together for you. It showcases the implementation.

Your ItemView function should be structured like this

const ItemView = ({ item }) => {
    return (
      <RectButton
        onPress={() =>
          navigation.navigate('LocationDataScreen', { item })
        } // This line passes all item keys as props for the next screen
        style={styles.searchcontainer}>
        <Text style={[styles.itemStyle, { textTransform: 'capitalize' }]}>
          {item.id}
          {item.country.toUpperCase()}
        </Text>
      </RectButton>
    );
  };

Your LocationDataScreen.js screen should resemble this

import * as React from 'react';
import { Text, View, StyleSheet } from 'react-native';
import Constants from 'expo-constants';

function LocationDataScreen({ route, navigation }) { // You can access props from here
  const { item } = navigation.state.params || {};
  return (
    <View style={styles.container}>
      <Text>Country Name - {item.name}</Text>
      <Text>Country Cases - {item.cases}</Text>
    </View>
  );
}

export default LocationDataScreen;

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    paddingTop: Constants.statusBarHeight,
    backgroundColor: '#ecf0f1',
    padding: 8,
  },
});

To set the Custom Header Title as item.country, follow this approach

In your ItemView function, adjust your onPress as shown below

onPress={() =>
          navigation.navigate('Screen2', { item: item, name: item.country })
        }

Your Stack.Screen configuration for the second screen should be set up like this

  <Stack.Screen
        name="Screen2"
        component={Screen2}
        options={({ route }) => ({
          headerTitle: route.params.name,
          headerShown: true,
        })}
      />

By clicking on the country, you'll now see its name displayed as the Header title.

Refer to my Snack for a demonstration of how it works.

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

An automatic conversion cannot handle spaces and prohibited characters in Object keys

The AlphaVantage API uses spaces and periods in the keys. Their API documentation is not formal, but you can find it in their demo URL. In my Typescript application, I have created data structures for this purpose (feel free to use them once we solve the ...

User's information will only be updated once the page is refreshed

I am encountering an issue with displaying two ul elements based on user login status. When I log in, the first ul is shown immediately, but the second ul is only displayed after a page refresh. Initially, the value in "accountService.currentUser" is null ...

Encountered an HttpErrorResponse while trying to access the API endpoint

I am encountering an issue when trying to update and insert data with a single post request. Below is my API code: Here is the service code: This section includes the function calling code: Additionally, this is the model being used The API C# model c ...

I am interested in utilizing Template literal types to symbolize placeholders

Currently, I am in the process of converting existing javascript files into typescript for my business needs. Below is an example object structure: [ { // Sample column names givenName, familyName, and picture are provided as examples. "giv ...

NX combined with Nest.js and TypeORM, further enhanced with Webpack and Migrations

Recently, I embarked on a project using NX (Nest.js + Angular) and set up TypeORM for database configuration. While everything runs smoothly in "serve" mode, I found myself struggling with configuring migrations. In a typical Nest.js project, all files in ...

javascript identify dissimilarities within arrays

Working on an Angular 2 application and attempting to identify the difference between two arrays (last seven days and missing dates within the last seven days). Everything works fine when initializing the array through a string, like in example code 1. How ...

Unable to successfully import Node, JS, or Electron library into Angular Typescript module despite numerous attempts

I'm still getting the hang of using stack overflow, so please forgive me if my question isn't formulated correctly. I've been doing a lot of research on both stack overflow and Google, but I can't seem to figure out how to import Electr ...

Tips for patiently anticipating the completed response within an interceptor

Using the interceptor, I want to display a loading spinner while waiting for subscriptions to complete. This approach works well in individual components by showing and hiding the spinner accordingly: ngOnInit() { this.spinnerService.show(); this. ...

Setting up tsconfig.json to enable support for either string literals or string templates involves adjusting the compiler options

After utilizing swagger codgen with the typescript-aurelia template to create API code, I noticed that a significant amount of string literals were being used in the resulting code. Despite encountering errors when running the transpiler tsc from the comma ...

Issue with React Redux: Store dispatch not causing component update

I have recently implemented React Redux in my project, but I seem to be encountering some issues. Despite changing the state, the value remains the same. I attempted to use useStore(), but it does not take any parameters. Can anyone provide insight into wh ...

Is it possible to create a map of functions that preserves parameter types? How can variadic tuple types in TypeScript v4 potentially enhance this

Initially, I faced a challenge when trying to implement a function similar to mapDispatchToProps in Redux. I struggled with handling an array of functions (action creators) as arguments, but managed to come up with a workaround that works, although it feel ...

Encountering issues with accessing the clientWidth and clientHeight references of the DOM in Vue

Issue with 'clientWidth' and 'clientHeight' properties on Vue and Element types. <div class="invoice-step-detail" id="invoice" ref="invoice"> @Component({ name: 'CreateInvoice', co ...

The MemoizedSelector cannot be assigned to a parameter of type 'string'

Currently, my setup involves Angular 6 and NgRX 6. The reducer implementation I have resembles the following - export interface IFlexBenefitTemplateState { original: IFlexBenefitTemplate; changes: IFlexBenefitTemplate; count: number; loading: boo ...

A step-by-step guide on creating a Decorator using the TypeScript compile API

How can I create a custom class in TypeScript with multiple 'class-validator' decorators to ensure the property types are correct? I am considering using `ts.factory.createDecorator`, but I'm unsure how to obtain a `ts.Expression` for it. ...

"Unleashing the power of React Native: A single button that reveals three different names

I have a piece of code that changes the name of a button from (KEYWORD) to a different one (KEYNOS) each time it is clicked. How can I modify it to change to a third value (KEYCH), where the default name is (A, B, C... etc), the first click shows Numbers ...

core.js encountered an error at line 6237: Unable to assign value to property 'area' as it is undefined

HTML: I have created a form but encounter an error when clicking the submit button. Can someone please assist me in identifying the issue? <h3 class="page-header">Operator Form</h3> <div class="outer-container"> <form class="form-s ...

What is the best way to utilize ngFor for iterating through a Map variable of classes in TypeScript?

In my TypeScript file, I have a class named `myMap` that contains a variable called `navList`, which is of type Map<string, string> and holds multiple key-value pairs. I am currently attempting to iterate over the values stored in `navList` within my ...

Obtain form data as an object in Vue when passed in as a slot

Currently, I am working on developing a wizard tool that allows users to create their own wizards in the following format: <wiz> <form> <page> <label /> <input /> </page> <page> <label /> ...

Conceal the HTML element within a subscription

Currently, I am utilizing Angular and have a checkbox that I need to toggle visibility based on the response of an API call subscription. The issue lies in a delay when trying to hide the checkbox (as it is initially set to visible). My assumption is that ...

Can a TypeScript generator function be accurately typed with additional functionality?

Generator functions come with prototype properties that allow for the addition of behavior. The generated generators inherit this behavior. Unfortunately, TypeScript does not seem to recognize this feature, leaving me unsure of how to make it aware. For i ...