React native expo - 从 FlatList 导航到详细信息屏幕
Posted
技术标签:
【中文标题】React native expo - 从 FlatList 导航到详细信息屏幕【英文标题】:React native expo - Navigate from FlatList to detail screen 【发布时间】:2020-05-07 18:03:01 【问题描述】:这里是 React Native 菜鸟。我正在尝试根据我的学习需求调整 React Native expo 选项卡式应用程序。我目前正在处理 Flatlists,我想打开一个新屏幕,将 FlatList 的任何项目作为项目道具的参数发送。我已经达到了某个点,但似乎无法成功完成它。
HomeScreen.js
import * as WebBrowser from 'expo-web-browser';
import React from 'react';
import Image,Platform,ScrollView,StyleSheet,Text,TouchableOpacity,View, from 'react-native';
import SafeAreaView from 'react-native';
import SearchableFlatList from '../navigation/SearchableList';
import MonoText from '../components/StyledText';
export default function HomeScreen()
return (
<SafeAreaView style= flex: 1, backgroundColor: '#fff' >
<SearchableFlatList/>
</SafeAreaView>
);
class LogoTitle extends React.Component
render()
return (
<React.Fragment>
<Image
source=require('../assets/images/icon.png')
style= width: 30, height: 30
/>
<Text style= fontSize: 30 >
AgriPrices
</Text>
</React.Fragment>
);
HomeScreen.navigationOptions =
headerTitle: () => <LogoTitle />,
headerStyle: backgroundColor: '#f4511e',,
headerTintColor: '#fff',
headerTitleStyle: fontWeight: 'bold',,
;
MainTabNavigator.js
import React from 'react';
import Platform from 'react-native';
import createStackNavigator from 'react-navigation-stack';
import createBottomTabNavigator from 'react-navigation-tabs';
import TabBarIcon from '../components/TabBarIcon';
import HomeScreen from '../screens/HomeScreen';
import LinksScreen from '../screens/LinksScreen';
import SettingsScreen from '../screens/SettingsScreen';
const config = Platform.select(web: headerMode: 'screen' ,default: ,);
const HomeStack = createStackNavigator(Home: HomeScreen,,config);
HomeStack.navigationOptions =
tabBarLabel: 'Home',
tabBarIcon: ( focused ) => (<TabBarIcon focused=focused name=Platform.OS === 'ios' ? `ios-home$focused ? '' : '-outline'` : 'md-home'/>),
;
HomeStack.path = '';
const LinksStack = createStackNavigator(Links: LinksScreen,,config);
LinksStack.navigationOptions =
tabBarLabel: 'Info',
tabBarIcon: ( focused ) => (<TabBarIcon focused=focused name=Platform.OS === 'ios' ? `ios-information-circle$focused ? '' : '-outline'` : 'md-information-circle'/>),
;
LinksStack.path = '';
const SettingsStack = createStackNavigator(Settings: SettingsScreen,,config);
SettingsStack.navigationOptions =
tabBarLabel: 'Settings',
tabBarIcon: ( focused ) => (<TabBarIcon focused=focused name=Platform.OS === 'ios' ? 'ios-settings' : 'md-settings' />),
;
SettingsStack.path = '';
const tabNavigator = createBottomTabNavigator(HomeStack,SettingsStack,LinksStack,);
tabNavigator.path = '';
export default tabNavigator;
SearchableFlatlist.js
import React, Component from 'react';
import View, Text, FlatList, ActivityIndicator, Alert from 'react-native';
import ListItem, SearchBar from 'react-native-elements';
import DetailsScreen from '../screens/DetailsScreen';
class MyFlatList extends Component
constructor(props)
super(props);
this.state =
loading: false,
data: [],
error: null,
;
this.arrayholder = [];
componentDidMount()
this.makeRemoteRequest();
makeRemoteRequest = () =>
const url = 'http://dummyurl.com';
this.setState( loading: true );
fetch(url)
.then(res => res.json())
.then(res =>
this.setState(data: res,error: res.error || null,loading: false,);
this.arrayholder = res;
)
.catch(error =>
this.setState( error, loading: false );
);
;
renderSeparator = () =>
return (
<View
style=
height: 1,
width: '86%',
backgroundColor: '#CED0CE',
marginLeft: '14%',
/>
);
;
searchFilterFunction = text =>
this.setState(
value: text,
);
const newData = this.arrayholder.filter(item =>
const itemData = `$item.description.toUpperCase() $item.product.toUpperCase() $item.product.toUpperCase()`;
const textData = text.toUpperCase();
return itemData.indexOf(textData) > -1;
);
this.setState(
data: newData,
);
;
_onPress(item)
this.props.navigation.navigate('Details', product: item.product,description: item.description,);
renderHeader = () =>
return (
<SearchBar
placeholder="Type Here..."
lightTheme
round
onChangeText=text => this.searchFilterFunction(text)
autoCorrect=false
value=this.state.value
/>
);
;
render()
if (this.state.loading)
return (
<View style= flex: 1, alignItems: 'center', justifyContent: 'center' >
<ActivityIndicator />
</View>
);
const myicons = [
title: 'Cotton',file: require('../assets/images/cotton.png'),,
title: 'Beef',file: require('../assets/images/beef.png'),,
title: 'Bananas',file: require('../assets/images/banana.png'),,
title: 'Butter',file: require('../assets/images/butter.png'),,
title: 'Cocoa',file: require('../assets/images/cocoa.png'),,
title: 'Coffee',file: require('../assets/images/coffee.png'),,
title: 'Corn',file: require('../assets/images/corn.png'),,
title: 'Cotton',file: require('../assets/images/cotton.png'),,
title: 'Eggs',file: require('../assets/images/eggs.png'),,
title: 'Meat',file: require('../assets/images/meat.png'),,
title: 'Milk',file: require('../assets/images/milk.png'),,
title: 'Oils',file: require('../assets/images/oil.png'),,
title: 'Oranges',file: require('../assets/images/orange.png'),,
title: 'Rice',file: require('../assets/images/rice.png'),,
title: 'Shrimps',file: require('../assets/images/shrimp.png'),,
title: 'Sugar',file: require('../assets/images/sugar.png'),,
title: 'Tea',file: require('../assets/images/tea.png'),,
title: 'Tobacco',file: require('../assets/images/tobacco.png'),,
title: 'Wheat',file: require('../assets/images/wheat.png'),,
title: 'Wool',file: require('../assets/images/wool.png'),,
title: 'Oats',file: require('../assets/images/oat.png'),,
title: 'Indexes',file: require('../assets/images/index.png'),,
];
const navigate = this.props.navigation;
return (
<View style= flex: 1 >
<FlatList
data=this.state.data
renderItem=( item ) => (
<ListItem
leftAvatar= source: myicons.filter(myitem => myitem.title === item.product)[0].file
title=item.description
rightTitle=item.price.toString()
subtitle=item.date
onPress=() => navigate('Details', product: item.product )
/>
)
keyExtractor=item => item.description
ItemSeparatorComponent=this.renderSeparator
ListHeaderComponent=this.renderHeader
/>
</View>
);
export default MyFlatList;
DetailsScreen.js
import React from 'react';
import Text, Image,ScrollView, StyleSheet from 'react-native';
export default function DetailsScreen()
var product =this.props.navigation.getParam('product', 'No Name'); //second parameter is a callback
return (
<View style= flex: 1, alignItems: 'center', justifyContent: 'center' >
<Text>The product is this.props.navigation.state.params.product||'NoName' /*NoName is also a callback*/</Text>
</View>
);
DetailsScreen.navigationOptions =
headerTitle: () => <LogoTitle />,
headerStyle:
backgroundColor: '#f4511e',
,
headerTintColor: '#fff',
headerTitleStyle:
fontWeight: 'bold',
,
;
class LogoTitle extends React.Component
render()
return (
<React.Fragment>
<Image
source=require('../assets/images/icon.png')
style= width: 30, height: 30
/>
<Text style= fontSize: 30 >
AgriPrices
</Text>
</React.Fragment>
);
const styles = StyleSheet.create(
container:
flex: 1,
paddingTop: 15,
backgroundColor: '#fff',
,
);
当我按下 HomeScreen 的 SearchableFlatList 的一项时,我需要打开 DetailsScreen,方法是将 description 作为参数传递。使用上面的代码,我得到一个错误 undefined is not an object (evalating 'this.props.navigation.navigate')。我怎样才能超越这个?
【问题讨论】:
【参考方案1】:我建议您使用堆栈导航器包装 MyFlatList 和 DetailsScreen。
const finalStack = createStackNavigator(
MyFlatList: MyFlatList,
DetailsScreen: DetailsScreen
,
headerMode: 'none'
);
完成此操作后,'this.props.navigation.navigate' 将不会未定义。 截至目前,这两个屏幕之间没有导航链接。
问:为什么我选择堆栈导航器? A:因为你不希望 FlatList 在屏幕切换上重复渲染。
【讨论】:
你指的是哪个文件?顺便说一句,感谢您的时间。 在 HomeScreen.js 中,将 SearchableFlatList 替换为我建议的堆栈导航器。如果您遇到任何问题,请告诉我。 如果我按照你的建议添加代码,它首先会给出一个未知变量 MyFlatList 的错误。因此,我在您的代码中将 FlatList 更改为 SearchableFlatList,就像在导入中一样。现在,它为 this.props.navigation.navigate 给出了相同的未定义错误。 我只是大致了解了它的工作原理,您不应该复制该代码。请在snack.expo.io 上进行工作演示。我帮你会更容易。 MyFlatList 应该是 HomeScreen.js 中的 SearchableFlatList以上是关于React native expo - 从 FlatList 导航到详细信息屏幕的主要内容,如果未能解决你的问题,请参考以下文章
从 Expo.MapView React-native 将 fitToSuppiedMarkers 应用到我的地图的正确方法是啥?
如何从 React Native Expo 推送通知中取消订阅(删除监听器)
React Native Expo 音频 |从最新位置播放直播
React native expo - 从 FlatList 导航到详细信息屏幕