如何基于路由导航实现RunningScreen返回时ReadyScreen的模态框切换?
路由传参与Modal触发的完整修复方案
一、修复RunningScreen的路由传参逻辑错误
你现有代码的核心传参问题集中在三点:
- 导航目标名称字符串未闭合:
'ReadyScreen缺少收尾单引号,会直接引发语法报错 - 逻辑层级错配:把
onPress属性写在checkFinish的返回值里,完全没有绑定到实际的按钮点击事件 - 导航方法使用不匹配:从RunningScreen回退到流程起点ReadyScreen时,不需要重复压入新的页面栈实例,否则会造成页面栈冗余
正确的RunningScreen端代码参考:
function RunningScreen({ navigation }) { // 运行结束的业务触发逻辑 const handleFinishRun = () => { navigation.navigate('ReadyScreen', { didComeFromRunningScreen: true, // 可随参数同步携带本次运行的全部展示数据 runSummary: { duration: 28, distance: 3.5, calories: 192 } }) } return ( <Button title="结束运行" onPress={handleFinishRun} /> ) }
二、实现ReadyScreen端的Modal正确切换逻辑
你现有实现的核心问题集中在三点:
- 未从路由对象中正确读取RunningScreen传递的参数
- 未及时清理已读取的路由参数,容易造成Modal无触发条件的重复弹出
- useFocusEffect的依赖设置不当,空依赖数组会导致闭包捕获的route参数始终是初始值,无法读取后续传入的新参数
正确的ReadyScreen端实现参考:
function ReadyScreen({ navigation, route }) { // 本地维护Modal显隐状态 const [isSummaryModalVisible, setIsSummaryModalVisible] = useState(false) // 存储本次运行的展示数据 const [currentRunInfo, setCurrentRunInfo] = useState(null) useFocusEffect( React.useCallback(() => { // 从路由参数中读取运行结束的标记与对应数据 const isFromRunning = route.params?.didComeFromRunningScreen const runInfo = route.params?.runSummary if (isFromRunning) { setCurrentRunInfo(runInfo) setIsSummaryModalVisible(true) // 读取完参数后立刻清空标记,避免残留参数触发重复弹窗 navigation.setParams({ didComeFromRunningScreen: undefined, runSummary: undefined }) } }, [route.params, navigation]) ) // Modal关闭逻辑 const closeModal = () => { setIsSummaryModalVisible(false) setCurrentRunInfo(null) } return ( <View> {/* ReadyScreen原有页面内容 */} <RunSummaryModal visible={isSummaryModalVisible} runInfo={currentRunInfo} onClose={closeModal} /> </View> ) }
关键注意事项
- 必须将
route.params加入useFocusEffect的依赖数组:否则回调会因闭包缓存拿到旧的路由值,无法响应RunningScreen传来的新参数 - 路由参数的清理操作必不可少:如果残留
didComeFromRunningScreen: true的标记,后续用户从ListScreen、CheckScreen返回ReadyScreen时,会无理由重复弹出运行总结Modal - 如果导航栈结构较深,可将
navigation.navigate替换为navigation.popToTop({ merge: true }),同样可以在返回栈底ReadyScreen时合并传入参数,避免重复创建页面实例
内容的提问来源于stack exchange,提问作者MK_Pierce
相关产品推荐
相关产品推荐

