如何修复React Native AuthScreen中NAVIGATE动作失效问题?
React Native 导航跳转失效问题解决方案
问题根源
你的代码核心问题在于导航栈配置逻辑错误:
- 在
App.js中,当isAdmin为false时,导航栈仅注册了AuthScreen,FormationScreen并未被包含在栈内,导致AuthScreen调用navigation.navigate('Formation')时找不到对应路由。 AuthScreen中多余导入了NavigationContainer,会干扰根导航容器的正常工作。
修复方案
1. 修改App.js导航栈配置
将所有需要的屏幕统一注册到导航栈中,通过登录状态控制初始路由,而非直接从栈中移除屏幕:
import React, { useState } from 'react'; import { NavigationContainer } from '@react-navigation/native'; import { createNativeStackNavigator } from '@react-navigation/native-stack'; import { Provider } from 'react-redux'; import store from './store'; import HomeScreen from './screens/HomeScreen'; import FormationScreen from './screens/FormationScreen'; import SummaryScreen from './screens/SummaryScreen'; import AddParticipantsScreen from './screens/AddParticipantsScreen'; import AuthScreen from './screens/AuthScreen'; const Stack = createNativeStackNavigator(); export default function App() { const [isAdmin, setIsAdmin] = useState(false); const [isAuthenticated, setIsAuthenticated] = useState(false); return ( <Provider store={store}> <NavigationContainer> <Stack.Navigator initialRouteName={isAuthenticated ? (isAdmin ? "Accueil" : "Formation") : 'Auth'} > {/* 注册所有需要的屏幕 */} <Stack.Screen name="Auth" options={{ headerShown: false }}> {(props) => <AuthScreen {...props} setIsAdmin={setIsAdmin} setIsAuthenticated={setIsAuthenticated} />} </Stack.Screen> <Stack.Screen name="Accueil" component={HomeScreen} /> <Stack.Screen name="Formation" component={FormationScreen} /> <Stack.Screen name="Résumé" component={SummaryScreen} /> <Stack.Screen name="Ajouter Participants" component={AddParticipantsScreen} /> </Stack.Navigator> </NavigationContainer> </Provider> ); }
2. 修复AuthScreen.js逻辑
- 移除多余的
NavigationContainer导入 - 简化登录后的导航逻辑,直接在登录函数中完成跳转,无需依赖
useFocusEffect - 正确使用传入的
setIsAuthenticated方法
import React, { useState } from 'react'; import { View, Text, Button, TextInput, StyleSheet, TouchableOpacity } from 'react-native'; import { useNavigation } from '@react-navigation/native'; export default function AuthScreen({ setIsAdmin, setIsAuthenticated }) { const [password, setPassword] = useState(''); const navigation = useNavigation(); const navigateToFormation = () => { setIsAdmin(false); setIsAuthenticated(true); navigation.navigate('Formation'); }; const handleAdminLogin = () => { if (password === 'test') { setIsAdmin(true); setIsAuthenticated(true); navigation.navigate('Accueil'); } else { alert('Mot de passe incorrect'); } }; const handlePlayerLogin = () => { navigateToFormation(); }; return ( <View style={styles.container}> <Text style={styles.title}>Page d'authentification</Text> <TextInput style={styles.input} placeholder="Mot de passe" secureTextEntry onChangeText={(text) => setPassword(text)} /> <Button title="Se connecter en tant qu'admin" onPress={handleAdminLogin} /> <Button title="Se connecter en tant que joueur" onPress={handlePlayerLogin} /> <TouchableOpacity style={styles.button} onPress={navigateToFormation}> <Text style={styles.buttonText}>🏐 JOUEURS 🏐</Text> </TouchableOpacity> </View> ); } const styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', alignItems: 'center', }, title: { fontSize: 20, fontWeight: 'bold', marginBottom: 16, }, input: { height: 40, borderColor: 'gray', borderWidth: 1, marginBottom: 16, padding: 8, width: '80%', }, button: { marginTop: 20, padding: 10, backgroundColor: '#e0e0e0', borderRadius: 5, }, buttonText: { fontSize: 16, fontWeight: 'bold', } });
3. 可选:页面权限控制
如果需要限制玩家访问管理员页面,可以在管理员专属页面(如HomeScreen)内添加校验:
// HomeScreen.js 示例 import React from 'react'; import { View, Text } from 'react-native'; import { useNavigation } from '@react-navigation/native'; export default function HomeScreen({ route }) { const navigation = useNavigation(); const { isAdmin } = route.params || {}; React.useEffect(() => { if (!isAdmin) { navigation.navigate('Formation'); } }, [isAdmin, navigation]); return ( <View> <Text>Accueil Admin</Text> </View> ); }
关键说明
- 导航栈必须包含所有需要跳转的屏幕,否则
navigation.navigate无法找到对应路由 - 登录状态更新后直接调用
navigation.navigate即可完成跳转,无需额外监听 - 多余的
NavigationContainer会导致导航上下文冲突,必须移除
内容的提问来源于stack exchange,提问作者MaxWell
相关产品推荐
相关产品推荐

