Expo Go仅在编辑页面刷新时闪退问题求助
针对你在EditProfile页面刷新时Expo Go崩溃的问题,以下是代码中存在的几个关键问题及修复方法:
1. 缺失必要的依赖导入
代码中使用了React核心API、Expo ImagePicker、Alert等模块,但未添加导入语句。刷新时模块找不到会直接导致崩溃。
修复:在文件顶部添加所有需要的导入:
import React, { useState, useEffect, useRef } from 'react'; import { View, Text, Alert } from 'react-native'; import * as ImagePicker from 'expo-image-picker'; import { Animated } from 'react-native'; // 导入你的AppButton组件 import AppButton from '../path/to/AppButton'; // 替换为实际路径
2. auth.currentUser 可能为null导致的报错
在updateProfile函数中直接访问auth.currentUser.uid,如果刷新时Firebase Auth还未完成初始化,currentUser会是null,访问uid会抛出错误导致崩溃。
修复:添加空值检查,同时在useEffect中监听auth状态变化:
// 替换原useEffect useEffect(() => { const unsubscribe = auth.onAuthStateChanged(user => { if (user) { db.collection("users") .doc(user.uid) .get() .then(snap => setUserData(snap.data())); } }); return unsubscribe; // 清理订阅 }, []); // 修复updateProfile中的uid访问 const updateProfile = async()=>{ if (!auth.currentUser) return; // 添加空值检查 let imgUrl = await uploadImage(); if(imgUrl == null && userData?.userImg){ imgUrl = userData.userImg } db.collection("users") .doc(auth.currentUser.uid) .set({ name: userData?.name || '', email: userData?.email || '', phone: userData?.phone || '', address: userData?.address || '', userImg: imgUrl || userData?.userImg || '' }) }
3. uploadImage 函数返回值异常
uploadImage是async函数,但内部使用snapshot.on的回调,没有正确返回Promise,导致await uploadImage()无法获取正确的下载URL,同时回调中return null不会作为函数返回值。
修复:将uploadImage改为返回Promise,正确处理URL返回:
const uploadImage = async ()=>{ if(image == null){ return null; } return new Promise((resolve, reject) => { const xhr = new XMLHttpRequest(); xhr.onload = function (){ const blob = xhr.response; const ref = firebase.storage().ref().child("images/" + new Date().toISOString()) const snapshot = ref.put(blob) snapshot.on( firebase.storage.TaskEvent.STATE_CHANGED, ()=>{ setUploading(true) }, (error)=>{ setUploading(false) console.log(error) blob.close(); reject(error); }, ()=>{ snapshot.snapshot.ref.getDownloadURL().then((url)=>{ setUserData(prev => ({...prev, userImg: url})); // 修正字段名 setUploading(false); console.log('download:', url) blob.close() resolve(url); // 返回下载URL }) } ) }; xhr.onerror = function (){ reject(new TypeError("Network request failed")) }; xhr.responseType = "blob" xhr.open("GET",image,true) xhr.send(null) }); }
4. ImagePicker结果字段拼写错误
OpenCamera函数中使用!result.cancelled,但Expo ImagePicker最新版本中取消字段是canceled(美式拼写),判断错误会导致后续访问result.uri失败。
修复:统一使用正确的字段名:
const OpenCamera = async () => { const {granted} = await ImagePicker.requestCameraPermissionsAsync() if (!granted){ Alert.alert("Donation", 'You need to enable permission from the settings to access the camera..!') return ; } let result = await ImagePicker.launchCameraAsync({ mediaTypes: ImagePicker.MediaTypeOptions.All, allowsEditing: true, aspect: [4, 3], quality: 1, onPress: () => sheetRef.current?.snapTo(1) // 修正为函数,添加空值检查 }); console.log(result); if (!result.canceled) { // 改为canceled setImage(result.assets[0].uri); // 统一使用assets数组 } };
5. sheetRef 调用时机错误
在ImagePicker的配置中,onPress:sheetRef.current.snapTo(1)会直接执行函数,导致组件渲染时就调用snapTo,此时sheetRef.current可能为null,引发报错。
修复:传递函数而非直接执行:
// 修复pickImage中的launchAsync配置 let result = await ImagePicker.launchImageLibraryAsync({ mediaTypes: ImagePicker.MediaTypeOptions.Images, allowsEditing: true, aspect: [4, 3], quality: 1, onPress: () => sheetRef.current?.snapTo(1) // 改为箭头函数,添加空值检查 });
6. 初始渲染时userData为null的问题
组件初始渲染时userData是null,若此时刷新页面,访问userData的属性会报错。
修复:在使用userData的地方添加空值可选链:
// 例如在渲染用户信息时(假设你有相关渲染代码) {userData?.name && <Text>{userData.name}</Text>}
内容的提问来源于stack exchange,提问作者Bashamlan Salem

