React Native导航配置:如何从Map与List跳转至GigDetails
React Native栈导航:实现List到GigDetails的跳转
我正在开发一款React Native演出指南应用,使用栈导航实现页面切换。需求如下:用户可从Map.js跳转至List.js查看演出列表,点击列表项需跳转至GigDetails.js查看详情;同时点击Map.js中的演出标记也需跳转至GigDetails.js。目前Map到GigDetails的跳转已实现,但不知如何配置路由实现List到GigDetails的跳转。
应用结构
screens/List.js <-----> screens/Map.js (Home screen) *| | *| | (GigDetails navigated to via map Marker Callout) *| | *GigDetails.js GigDetails.js
现有代码
App.js
import 'react-native-gesture-handler'; import { StyleSheet, Text, View } from 'react-native'; import { NavigationContainer } from '@react-navigation/native'; import { MyStack } from './routes/homeStack'; export default function App() { return ( <NavigationContainer> <MyStack/> </NavigationContainer> ); }
HomeStack.js
import { createStackNavigator } from "@react-navigation/stack"; import List from '../screens/List' import Map from '../screens/Map' import Header from "../components/Header"; import GigDetails from "../screens/GigDetails"; const Stack = createStackNavigator() export const MyStack = () => { return ( <Stack.Navigator initialRouteName="Map" > <Stack.Screen name="Map" component={Map} options={{ headerTitle: () => <Header/>, headerTitleAlign: 'center' }} /> <Stack.Screen name="List" component={List} options={{ headerTitle: () => <Header/>, headerTitleAlign: 'center' }} /> <Stack.Screen name="GigDetails" component={GigDetails} options={{ headerTitle: () => <Header/>, headerTitleAlign: 'center' }} /> </Stack.Navigator> ); };
Map.js
import { StyleSheet,View,Text,Pressable } from 'react-native' import GigMap from '../components/GigMap' const Map = ({ navigation }) => { return ( <View style = {styles.container}> <GigMap navigation = {navigation}/> <View style = {styles.footer}> <Pressable title = "Go to list view" onPress = {() => navigation.navigate("List")} style = {styles.button} > <Text style = {styles.buttonText}>List View</Text> </Pressable> </View> </View> ) }
GigMap.js
import { useState,useEffect } from 'react'; import { StyleSheet, Text, View,Pressable } from 'react-native'; import MapView from 'react-native-maps'; import { Marker,Callout } from 'react-native-maps'; import { query,collection,getDocs } from 'firebase/firestore'; import { db } from '../firebase'; import CalloutView from './CalloutView'; import { mapStyle } from '../util/mapStyle'; import dayjs from 'dayjs'; const GigMap = ({ navigation }) => { const [gigs, setGigs] = useState([]); const [ date,setDate ] = useState(dateToday) const [ daysAdded,setDaysAdded ] = useState(1) //生成当前日期 const addHours =(numOfHours, date = new Date()) => { date.setTime(date.getTime() + numOfHours * 60 * 60 * 1000); return date; } let localDate = addHours(13) useEffect(() => { setDate(localDate) },[]) const addDay = () => { setDaysAdded(daysAdded+1) localDate.setDate(localDate.getDate() + daysAdded) setDate(localDate) } console.log(date) const day = new Date().getDate(); const month = new Date().getMonth() + 1; const year = new Date().getFullYear(); const dateToday = `${day}/${month}/${year}`; //调用Firebase获取'gigs'集合中的演出文档 useEffect(() => { const getGigs = async () => { try { const gigArray = []; const q = query(collection(db, "gigs")); const querySnapshot = await getDocs(q); querySnapshot.forEach((doc) => gigArray.push({ id: doc.id, ...doc.data() }) ); setGigs(gigArray); } catch (err) { console.log(`Error: ${err}`); } }; getGigs(); }, []); //筛选出当天的演出 const gigsToday = gigs.filter((gig) => gig.date === dateToday); return ( <View style={styles.container}> <Text style={styles.headerText}>今日演出</Text> <MapView initialRegion={{ latitude: -41.29416, longitude: 174.77782, latitudeDelta: 0.03, longitudeDelta: 0.03, }} style={styles.map} customMapStyle={mapStyle} > {gigsToday.map((gig, i) => ( <Marker key={i} coordinate={{ latitude: gig.location.latitude, longitude: gig.location.longitude, }} image={require("../assets/Icon_Gold_48x48.png")} > <Callout style={styles.callout} onPress={() => navigation.navigate("GigDetails", { venue: gig.venue, date: gig.date, gigName: gig.gigName, time: gig.time, }) } > <CalloutView venue={gig.venue} date={gig.date} gigName={gig.gigName} time={gig.time} style={styles.calloutView} /> </Callout> </Marker> ))} </MapView> <View style = {styles.buttonOptions}> <Pressable > <Text style = {styles.buttonOptionsText}>查看昨日演出</Text> </Pressable> <Pressable onPress = {addDay}> <Text style = {styles.buttonOptionsText}>查看明日演出</Text> </Pressable> </View> </View> ); };
List.js
import { View,Text } from 'react-native' import ListByDay from '../components/ListByDay'; const List = () => { return ( <View> <ListByDay/> </View> ) } export default List;
ListByDay.js
import { StyleSheet, Text, View,FlatList,TouchableOpacity } from 'react-native'; import { useGigs } from '../hooks/useGigs'; const ListByDay = ({ navigation }) => { const gigs = useGigs() return ( <View> <Text style = {styles.header}>今日演出</Text> <FlatList data = {gigs} renderItem = {({ item }) => ( <TouchableOpacity style = {styles.test}> <Text>{item.venue}</Text> <Text>{item.gigName}</Text> <Text>{item.date}</Text> <Text>{item.time}</Text> </TouchableOpacity> )} /> </View> ); } const styles = StyleSheet.create({ test: { borderWidth:1, borderColor:'black', }, header: { padding:10 } }) export default ListByDay;
解决方案
你的路由配置已经正确,HomeStack.js中已注册GigDetails页面,只需完成两个步骤即可实现List到GigDetails的跳转:
- 在List.js中传递navigation给ListByDay组件
修改List.js,接收并传递navigation属性给子组件:
import { View,Text } from 'react-native' import ListByDay from '../components/ListByDay'; const List = ({ navigation }) => { return ( <View> <ListByDay navigation={navigation} /> </View> ) } export default List;
- 给ListByDay中的TouchableOpacity添加跳转逻辑
修改ListByDay.js里的TouchableOpacity,添加onPress事件,调用navigation.navigate跳转到GigDetails并传递演出参数:
<FlatList data = {gigs} renderItem = {({ item }) => ( <TouchableOpacity style = {styles.test} onPress={() => navigation.navigate("GigDetails", { venue: item.venue, date: item.date, gigName: item.gigName, time: item.time, })} > <Text>{item.venue}</Text> <Text>{item.gigName}</Text> <Text>{item.date}</Text> <Text>{item.time}</Text> </TouchableOpacity> )} />
修改完成后,点击列表中的任意演出项即可跳转到对应的详情页面。
内容的提问来源于stack exchange,提问作者Josh Simon
相关产品推荐
相关产品推荐

