React-Navigation如何在ProgramsScreen内实现单项目自动跳转并移除自身堆栈
你的思路完全可行,通过useFocusEffect配合navigation.replace就能完全满足需求,且所有逻辑都封装在ProgramsScreen内部,不需要修改外部的跳转逻辑,具体实现方案如下:
核心实现原理
navigation.replace会直接用新页面替换导航堆栈中当前的Programs页面,跳转完成后堆栈里就不会保留Programs页面,不管是点击左上角返回按钮、系统返回键还是手势返回,都会直接跳过该页面,符合你的要求。useFocusEffect保证每次页面获得焦点时都会重新执行项目数量检查,覆盖所有进入该页面的场景。
完整代码示例
import { useFocusEffect, useNavigation } from '@react-navigation/native'; import { useState, useCallback } from 'react'; import { View, ActivityIndicator, Text, FlatList } from 'react-native'; const ProgramsScreen = () => { const navigation = useNavigation(); const [programList, setProgramList] = useState([]); const [loading, setLoading] = useState(true); useFocusEffect( useCallback(() => { // 避免组件卸载后仍然执行状态更新导致报错 let isMounted = true; const checkProgramCount = async () => { // 这里替换为你实际获取项目列表的逻辑,可以是接口请求、从全局状态读取等 const res = await fetch('你的项目列表接口地址'); const list = await res.json(); if (!isMounted) return; setProgramList(list); setLoading(false); // 项目数量为1时直接跳转,替换当前页面 if (list.length === 1) { navigation.replace('ProgramNav', { screen: 'Class List', params: { programId: list[0].id } }); } }; checkProgramCount(); return () => { isMounted = false; }; }, [navigation]) ); // 加载中或者满足自动跳转条件时,展示loading占位,避免页面闪烁 if (loading || programList.length === 1) { return ( <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}> <ActivityIndicator size="large" /> </View> ); } // 项目数量大于1时,正常渲染项目列表页面 return ( <View style={{ flex: 1 }}> <FlatList data={programList} keyExtractor={(item) => item.id.toString()} renderItem={({ item }) => ( <Text onPress={() => { navigation.navigate('ProgramNav', { screen: 'Class List', params: { programId: item.id } }) }}> {item.name} </Text> )} /> </View> ); }; export default ProgramsScreen;
额外说明
如果你的项目列表存储在Redux、Zustand等全局状态中,不需要每次进入页面请求,直接读取全局状态做判断即可,逻辑完全一致。
内容的提问来源于stack exchange,提问作者Archimedes Trajano
相关产品推荐
相关产品推荐

