You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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的跳转:

  1. 在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;
  1. 给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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 08:15:36