React Native 自定义函数组件内触发navigation导航跳转的问题咨询
React Native子组件触发导航跳转实现方案
你可以通过以下3种常用方式实现需求,根据项目结构选择适配的方案即可:
方案1:子组件直接调用useNavigation钩子(最简便)
React Navigation提供了useNavigation钩子,所有在导航上下文内的组件都可以直接调用获取navigation对象,不需要逐层传递:
- 第一步:在NewOrderPopUp组件顶部引入钩子
import { useNavigation } from '@react-navigation/native';
- 第二步:在NewOrderPopUp组件内部调用钩子获取对象,更新toggleAcceptBooking函数:
function NewOrderPopUp({id, services, name, rating, accepted, destinationPlaceName, userPlaceName, driverName, driverContactNumber, driverRating, driverTrackingNumber}) { // 新增代码 const navigation = useNavigation(); async function toggleAcceptBooking() { await firestore() .collection('userBookingRequest') .doc(id) .update({ accepted : !accepted, driverName: 'Sample Driver', driverContactNumber: '09123456789', driverRating: '4.9', driverPlateNumber: 'NFT-2020', driverTrackingNumber: GenerateTrackingNumber(), }) CheckIfBookingAccepted(); // 新增跳转代码 navigation.navigate('BookingPage'); } return ( <View>....</View> ); }
该方案不需要修改HomeScreen的代码,适合NewOrderPopUp仅在导航栈页面内调用的场景。
方案2:从父组件HomeScreen传递navigation属性
如果项目版本不支持useNavigation钩子,也可以从作为路由页面的HomeScreen把navigation传递给子组件:
- 第一步:HomeScreen获取navigation对象,传递给NewOrderPopUp
import NewOrderPopUp from "../../components/NewOrderPopUp"; import { useNavigation } from '@react-navigation/native'; const HomeScreen = () => { const navigation = useNavigation(); //... 其他代码 return ( <View> <FlatList horizontal contentContainerStyle={{paddingHorizontal: 30}} data={userBookingData} keyExtractor={(item) => item.id} renderItem={({item}) => <NewOrderPopUp {...item} navigation={navigation}/>} /> </View> ); }
- 第二步:在NewOrderPopUp的入参里接收navigation属性,在toggleAcceptBooking执行完毕后调用
navigation.navigate('BookingPage')即可,调用逻辑和方案1一致。
方案3:父组件传递跳转回调函数(最解耦)
如果后续NewOrderPopUp可能在非导航场景下复用,推荐用回调的方式,把跳转逻辑放在父组件实现:
- 第一步:HomeScreen定义跳转回调,传递给子组件
import NewOrderPopUp from "../../components/NewOrderPopUp"; import { useNavigation } from '@react-navigation/native'; const HomeScreen = () => { const navigation = useNavigation(); // 定义跳转回调 const handleBookingAccepted = () => { navigation.navigate('BookingPage'); } //... 其他代码 return ( <View> <FlatList horizontal contentContainerStyle={{paddingHorizontal: 30}} data={userBookingData} keyExtractor={(item) => item.id} renderItem={({item}) => <NewOrderPopUp {...item} onBookingAccepted={handleBookingAccepted}/>} /> </View> ); }
- 第二步:NewOrderPopUp接收回调,数据更新完成后触发
function NewOrderPopUp({id, services, name, rating, accepted, destinationPlaceName, userPlaceName, driverName, driverContactNumber, driverRating, driverTrackingNumber, onBookingAccepted}) { async function toggleAcceptBooking() { await firestore() .collection('userBookingRequest') .doc(id) .update({ accepted : !accepted, driverName: 'Sample Driver', driverContactNumber: '09123456789', driverRating: '4.9', driverPlateNumber: 'NFT-2020', driverTrackingNumber: GenerateTrackingNumber(), }) CheckIfBookingAccepted(); // 触发父组件传递的回调 onBookingAccepted?.(); } return ( <View>....</View> ); }
该方式子组件不需要依赖导航模块,复用性更高。
内容的提问来源于stack exchange,提问作者Ginxxx
相关产品推荐
相关产品推荐

