React Native登录页AsyncStorage报错:TypeError问题求助
问题
开发React Native登录页面时,使用AsyncStorage存储token实现自动登录,运行时报错:
Unhandled promise rejection: TypeError: undefined is not an object (evaluating '_asyncStorage.AsyncStorage.getItem')
相关代码如下:
import { StatusBar } from 'expo-status-bar'; import { StyleSheet, Text, View, FlatList, Image, Button } from 'react-native'; import { FontAwesomeIcon } from '@fortawesome/react-native-fontawesome'; import { faStar } from '@fortawesome/free-solid-svg-icons' import React, {useState, useEffect} from 'react' import { TextInput } from 'react-native-gesture-handler'; import { AsyncStorage } from '@react-native-async-storage/async-storage'; export default function Login(props) { const [ username, setUsername] = useState("") const [ password, setPassword] = useState("") useEffect(()=> { getData(); }, []) const auth = () => { fetch(`http://192.168.5.213:8000/auth/`, { method: 'POST', headers: { "Content-Type": 'application/json' }, body: JSON.stringify({ username: username, password: password}), }) .then( res => res.json()) .then( res => { saveData(res.token) props.navigation.navigate("MovieList") }) .catch( error => console.log(error)) props.navigation.goBack(); } const saveData = async (token)=> { await AsyncStorage.setItem('Token', token) } const getData = async () => { const token = await AsyncStorage.getItem('Token'); if(token) props.navigation.navigate("MovieList") } return ( <View style={styles.container}> <Text style={styles.label}> Username</Text> <TextInput style={styles.input} placeholder="Username" onChangeText={ text => setUsername(text) } value={username} /> <Text style={styles.label}> Password</Text> <TextInput style={styles.input} placeholder="Password" onChangeText={ text => setPassword(text) } value={password} secureTextEntry={true} autoCapitalize={'none'} /> <Button onPress= {() => auth()} title="Login"/> </View> ); } Login.navigationOptions = screenProps => ({ title: "Login", headerStyle: { backgroundColor: 'orange', }, headerTintColor: '#fff', headerTitleStyle: { fontWeight: 'bold', fontSize: 24, }, }) const styles = StyleSheet.create({ container: { flex: 1, padding: 10, backgroundColor: '#282C35', }, label: { fontSize: 24, color: "white", padding: 10, }, input: { fontSize: 24, backgroundColor: "white", padding: 10, margin: 10, }, item: { flex: 1, padding: 10, height: 50, backgroundColor: '#282C35' }, itemText: { color:'#ffff', fontSize: 24, }, starContainer: { alignItems: "center", justifyContent: "center", flexDirection: "row", }, orange: { color: 'orange', }, white: { color: 'white', }, description: { fontSize: 20, color: 'white', padding: 10, }, });
解决方法
1. 修正AsyncStorage导入方式
@react-native-async-storage/async-storage采用默认导出,而非命名导出。将导入代码修改为:
import AsyncStorage from '@react-native-async-storage/async-storage';
2. 为异步函数添加错误捕获
异步操作未处理错误会触发Promise拒绝警告,给saveData和getData添加try/catch:
- 修改
saveData:
const saveData = async (token)=> { try { await AsyncStorage.setItem('Token', token) } catch (error) { console.error('保存token失败:', error); } }
- 修改
getData:
const getData = async () => { try { const token = await AsyncStorage.getItem('Token'); if(token) props.navigation.navigate("MovieList") } catch (error) { console.error('获取token失败:', error); } }
3. 修复auth函数逻辑错误
props.navigation.goBack()会在请求完成前执行,导致页面提前跳转。删除该行代码(已调用navigate,无需额外返回):
const auth = () => { fetch(`http://192.168.5.213:8000/auth/`, { method: 'POST', headers: { "Content-Type": 'application/json' }, body: JSON.stringify({ username: username, password: password}), }) .then( res => res.json()) .then( res => { saveData(res.token) props.navigation.navigate("MovieList") }) .catch( error => console.log(error)) }
4. 确保依赖正确安装
如果尚未安装@react-native-async-storage/async-storage,执行对应命令安装:
# npm npm install @react-native-async-storage/async-storage # yarn yarn add @react-native-async-storage/async-storage
Expo项目无需额外配置;裸RN项目需执行pod install(iOS)或同步gradle(Android)。
内容的提问来源于stack exchange,提问作者Itay Lador
相关产品推荐
相关产品推荐

