React Native跨屏导航失效 运行白屏无页面显示问题求助
问题根因排查
当前启动白屏、路由不渲染是多个写法错误共同导致的,按影响优先级排序:
- 核心白屏原因:App.tsx中包裹
NavigationContainer的外层View设置了alignItems: 'center'和justifyContent: 'center',React Navigation的导航容器默认需要撑满父级全部可用空间,被居中属性约束后导航容器实际渲染尺寸为0,直接导致所有页面无法显示。 - 导航实例创建位置错误:栈导航实例
RootStack写在App组件函数体内部,每次组件重渲染都会重新创建导航实例,会导致导航状态丢失、渲染异常。 - 页面props接收错误:Login页面直接把
navigation作为组件参数,实际上屏幕组件接收的是包含navigation、route的整体props对象,直接调用navigation.navigate会触发非函数报错。 - 跳转按钮事件写法错误:注册按钮的
onPress={() => navigateToSignUp}仅返回函数引用,没有实际执行跳转逻辑,点击按钮无响应。 - 注册页根容器样式缺失:SignUp页面根View没有设置
flex:1,跳转后内容可能出现布局异常。
修正后的代码
App.tsx
import React from "react"; import { StyleSheet, View, Text} from 'react-native'; import { NavigationContainer } from '@react-navigation/native'; import { createNativeStackNavigator } from '@react-navigation/native-stack'; import Login from './src/screens/Login/login' import SignUp from './src/screens/SignUp/signUp' import { getItem } from './src/utility/AsyncStorage' // 导航实例移到组件外部创建,避免重渲染时重建 const RootStack = createNativeStackNavigator(); export default function App() { const [gmailId, setGmailId] = React.useState(""); const [password, setPassword] = React.useState(""); React.useEffect(() => { getItem("gmailId").then((value:any) => {setGmailId(value)}); getItem("password").then((value:any) => {setPassword(value)}); }, []); return ( <View style={styles.container}> <NavigationContainer> <RootStack.Navigator initialRouteName="Login"> <RootStack.Screen name="Login" component={Login} /> <RootStack.Screen name="signup" component={SignUp} /> </RootStack.Navigator> </NavigationContainer> </View> ); } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#fff', // 删除会导致导航容器尺寸为0的两个居中属性 // alignItems: 'center', // justifyContent: 'center', } });
login.tsx
import React from "react"; import { Text, View, Image, TextInput, TouchableOpacity} from 'react-native'; import { SocialIcon } from 'react-native-elements' import { loginStyle } from './loginStyle' import { signIn } from './loginLogic' // 修正props接收方式,从props中解构出navigation const Login = ({navigation}:any) => { const [gmailId, setGmailId] = React.useState(""); const [password, setPassword] = React.useState(""); const navigateToSignUp = () => { navigation.navigate('signup') }; return ( <View style={styles.container}> <Image style={styles.tinyLogo} source={require( "../../../assets/icon.png")} /> <View style={{ width: '100%', alignItems: 'center', justifyContent: 'center', marginTop: 30}}> <TextInput style={styles.input} placeholder="Enter Gmail Id" onChangeText={setGmailId} /> <TextInput style={styles.input} onChangeText={setPassword} placeholder="Enter your Password" secureTextEntry={true} /> <TouchableOpacity style={[styles.button, styles.loginButton]} onPress={()=>signIn(gmailId, password)}> <Text style={styles.text}>Login</Text> </TouchableOpacity> <TouchableOpacity style={[styles.button, styles.signupButton]} // 修正事件写法,直接传入跳转函数引用 onPress={navigateToSignUp}> <Text style={styles.text}>Create New Account</Text> </TouchableOpacity> </View> <View style={{flexDirection: 'row', alignItems: 'center', width: '95%', margin: 10, marginTop: 25}}> <View style={{flex: 1, height: 1, backgroundColor: 'black'}} /> <View> <Text style={{width: 100, textAlign: 'center'}}>Social Login</Text> </View> <View style={{flex: 1, height: 1, backgroundColor: 'black'}} /> </View> <SocialIcon style={{width:"85%"}} title='Sign In With Google' button type='google' onPress={()=>{console.log('Sign In With Google')}} /> </View> ) } export default Login //===================== STYLE SECTION ===================== const styles = loginStyle()
SignUp.tsx
import { StyleSheet, Text, View } from 'react-native' import React from 'react' const SignUp = () => { return ( // 给根容器加flex:1撑满全屏 <View style={{flex:1}}> <Text>signUp</Text> </View> ) } export default SignUp const styles = StyleSheet.create({})
验证说明
修改完成后重新重载应用,Login页面会正常渲染,点击Create New Account按钮即可正常跳转到SignUp页面。后续如果要实现记住登录状态的逻辑,不要在导航容器外条件渲染独立页面,要通过导航的初始路由配置、条件渲染Screen的方式实现,避免和导航组件的布局逻辑冲突。
内容的提问来源于stack exchange,提问作者Soumyanetra Pal
相关产品推荐
相关产品推荐

