React Native使用react-navigation登录跳转主页报错求助
问题修复方案
核心错误原因
- 你使用的是react-navigation 4.x版本,只有路由注册的页面组件能直接拿到
navigation属性,navigate是navigation对象下的方法,不能单独解构也无法直接从react-navigation-stack导入使用 - 登录成功后没有执行跳转逻辑,也没有正确将
navigation属性传递给EmailForm组件 - 你在
EmailForm中单独解构了不存在的navigate参数,调用时自然会报未定义,要是navigation没有从父组件正确传入,访问其属性就会触发Cannot read properties of undefined (reading 'props')报错
具体修改步骤
1. 修改EmailForm组件代码
首先删除无用的navigate解构,登录成功后调用navigation.navigate执行跳转,修改后代码如下:
const EmailForm = ({ buttonText, children, onAuthentication, navigation}) => { const [email, onChangeEmail] = useState('') const [password, onChangePassword] = useState('') const [token, setToken] = useState(''); const [errorMessage, setErrorMessage] = useState(''); const [loggedIn, setLoggedIn] = useState(false) const [showing, setShowing] = useState(false) async function submit(e) { e.preventDefault() console.log(email) console.log(password) axios .post('http://Ipv4:5000/api/auth/login', { email: email, password: password, }) .then((response) => { console.log(response.data) setToken(response.data.token) setLoggedIn(true) setShowing(true) // 新增跳转逻辑,不需要回退到登录页可以用replace代替navigate navigation.navigate('Home') // navigation.replace('Home') }) .catch((error) => { console.log(error.response.data) setErrorMessage(error.response.data.error) setLoggedIn(false) setShowing(true) }) } return ( <> <ScrollView contentContainerStyle={styles.container}> <Image style={styles.image} source={require('./plate.png')} /> <TextInput style={styles.input} onChangeText={(text) => onChangeEmail(text)} value={email} keyboardType="email-address" autoCapitalize="none" /> <TextInput style={styles.input} onChangeText={(text) => onChangePassword(text)} value={password} secureTextEntry /> <Button title={buttonText} onPress={submit}/> </ScrollView> {showing ? <Text>{loggedIn ? <Text style = {styles.loginmsg}>Success!!</Text> : <Text style={styles.errormsg}> Error! {errorMessage} </Text> } </Text> : null} </> ) }
2. 修正LoginScreen组件传参
你路由里注册的LoginScreen组件会自动拿到navigation属性,在LoginScreen里渲染EmailForm时,必须把navigation传递给EmailForm,示例如下:
// LoginScreen.js代码示例 import React from 'react' import EmailForm from './EmailForm' // 替换成你实际的导入路径 const LoginScreen = ({navigation}) => { return ( <EmailForm buttonText="登录" navigation={navigation} // 必须传这个参数 // 其他你需要传的参数 /> ) } export default LoginScreen
3. 修正App.js代码
删除无用的navigate导入,修改后导入部分如下:
import { createStackNavigator } from 'react-navigation-stack';
补充优化方案
如果不想逐层传递navigation属性,可以安装对应4.x版本的react-navigation-hooks,在EmailForm中直接调用useNavigation()获取navigation对象,不需要父组件传参:
// 先安装依赖:npm install react-navigation-hooks import { useNavigation } from 'react-navigation-hooks' const EmailForm = ({ buttonText, children, onAuthentication}) => { const navigation = useNavigation() // 直接获取navigation // 剩下的逻辑和之前一样 }
内容的提问来源于stack exchange,提问作者Anonymos
相关产品推荐
相关产品推荐

