React Native中设置initialRouteName为Login时Stack Navigation跳转失效
问题原因
核心错误是在Stack.Navigator内部用React Fragment(<>)包裹了所有Stack.Screen组件。Native Stack Navigator要求必须将Stack.Screen直接作为导航器的子元素,Fragment会破坏导航栈的路由注册逻辑:当Login作为初始路由时,导航系统无法正确识别StackHome的路由配置,导致跳转失败;而从Drawer进入Login时,处于独立的导航上下文,不受这个错误影响。
解决方案
- 移除
Stack.Navigator内部的<>包裹,直接将Stack.Screen作为导航器的直接子元素 - 可选优化:Login组件中同时使用了props传递的
navigation和useNavigation钩子,保留其中一个即可,避免冗余
修改后的app.js代码
const Stack = createNativeStackNavigator(); const HomeStack = () => { useEffect(() => { Translation.setLanguage('en'); }, []); return ( <Stack.Navigator initialRouteName="Login" screenOptions={{ headerShown: false, }} > <Stack.Screen name="preloader" component={Preloader} /> <Stack.Screen name="Login" component={Login} /> <Stack.Screen name="StackHome" component={HomeDrawer} /> <Stack.Screen name="Signup" component={Signup} /> </Stack.Navigator> ); }; const App = () => { return ( <Provider store={store}> <PersistGate loading={null} persistor={persistor}> <NavigationContainer>{HomeStack()}</NavigationContainer> </PersistGate> </Provider> ); }; export default App;
优化后的login.js代码(可选)
const Login = ({navigation}) => { const settings = useSelector(state => state.setting.settings); const isFocused = useIsFocused(); const dispatch = useDispatch(); const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); const [secureP, setSecureP] = useState(true); const [emailValid, setEmailValid] = useState(false); const [loader, setLoader] = useState(false); const [showAlert, setShowAlert] = useState(false); const [type, setType] = useState(''); const [title, setTitle] = useState(''); const [desc, setDesc] = useState(''); const [loading, setLoading] = useState(false); const validateEmail = userEmail => { let reg = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w\w+)+$/; if (reg.test(userEmail) === false) { setEmailValid(false); return false; } else { setEmailValid(true); setEmail(userEmail); } }; const login = () => { setLoading(true); if (email != '' && password != '') { axios .post(Constant.BaseUrl + 'user/do_login', { username: email, password: password, }) .then(async response => { console.log("response",response) if (response.data.type == 'success') { setLoading(false); dispatch(updateToken(response.data.authToken)); dispatch(updateUserInfo(response.data.profile.umeta)); dispatch(updateProfileInfo(response.data.profile.pmeta)); dispatch(updateBilling(response.data.profile.billing)); dispatch(updateShipping(response.data.profile.shipping)); dispatch( updateProfileImage(response.data.profile.pmeta.profile_img), ); dispatch( updateProfileBannerImage(response.data.profile.pmeta.banner_img), ); dispatch(updateProfileName(response.data.profile.pmeta.full_name)); dispatch(updateVerified(response.data.profile.pmeta._is_verified)); navigation.navigate('StackHome'); } else if (response.data.type == 'error') { setLoading(false); setShowAlert(true); setType(response.data.type); setTitle(response.data.title); setDesc(response.data.message); } }) .catch(error => { setLoading(false); console.log(error); }); } else { setShowAlert(true); setType('error'); setTitle(Translation.globalOops); setDesc(Translation.globalEnterData); setLoading(false); } }; const hideAlert = () => { setShowAlert(false); }; // return the view etc... };
内容的提问来源于stack exchange,提问作者Andre van Rensburg
相关产品推荐
相关产品推荐

