FlatList onPress 到带有数据的不同屏幕

FlatList onPress to different screen with data

我在平面列表中有一个国家列表,其中包含我使用 API 创建的搜索过滤器。我想这样做,所以当我在平面列表中按下一个国家的名称时,它会将我带到一个屏幕,在该屏幕上打印出该特定国家的名称及其案例数。 LocationDataScreen 是我要打印出该信息的屏幕。感谢您的帮助:)

下面是我当前的代码:

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

查看我为您创建的 Snack。它有实现。

您的 ItemView 函数应如下所示

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

您的 LocationDataScreen.js 屏幕应该如下所示

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,
  },
});

对于 Custom Header Title 作为 item.country 我们可以这样做

在你的 ItemView 函数中你的 onPress 应该是这样的

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

第二个屏幕的 Stack.Screen 部分应该如下所示

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

现在,当您点击国家/地区时,您会在顶部看到其名称 Header 标题。

检查我的 Snack 以查看工作示例。

您需要将数据作为 props 传递给 LocationDataScreen.tsx。以下是您的操作方法。

您的 onPress 函数应如下所示:

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

而要获取传过来的数据,可以在生命周期函数中写这段代码(例如:componentDidMount()等)

   this.props.navigation.state.params

您也可以直接将其保存在屏幕 stateLocationDataScreen.tsxLocationDataScreen.tsx 的代码在使用 Class:

时看起来像这样
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;

同时使用 函数

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

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

你的堆栈导航器也应该看起来像这样

  const CountryRoute = createStackNavigator(
  {
       CountryList: {
         screen: CountryList,
       },
       
       LocationDataScreen: {
         screen: LocationDataScreen, 
       },
    
  },
  {
    initialRouteName: 'CountryList',
  },
);

对于 StackNavigation,我使用的是:

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

应该是这样。