React Native Expo:用户选中图片后立即上传至Firebase Storage实现问题
实现方案
只需新增一个监听image状态变化的副作用钩子即可实现选中图片后自动上传,具体修改如下:
调整点说明
- 修正
uploading状态的初始值:原代码初始设为空字符串,不符合布尔类型使用逻辑,改为false - 新增依赖
image的useEffect:当image被赋值为有效图片uri时,自动触发上传+更新Firestore全流程 - 可选优化:修复
getPictureBlob方法硬编码使用外部image变量的问题,改为使用入参uri,逻辑更严谨;同时加上传中判定避免重复触发选图
修改后完整代码
const [image, setImage] = useState(null); const [userData, setUserData] = useState(""); // 修正初始值为布尔类型 const [uploading, setUploading] = useState(false); const getPermission = async () => { if (Platform.OS !== "web") { const { status } = await ImagePicker.requestMediaLibraryPermissionsAsync(); if (status !== "granted") { alert("Sorry, we need camera roll permissions to make this work!"); } } }; const getUserData = async () => { await firebase .firestore() .collection("users") .doc(firebase.auth().currentUser.uid) .get() .then((documentSnapshot) => { if (documentSnapshot.exists) { setUserData(documentSnapshot.data()); } }); }; const pickImage = async () => { // 上传中禁止重复选图 if (uploading) return let result = await ImagePicker.launchImageLibraryAsync({ mediaTypes: ImagePicker.MediaTypeOptions.All, allowsEditing: true, aspect: [4, 3], quality: 1, }); if (!result.cancelled) { setImage(result.uri); } }; const getPictureBlob = (uri) => { return new Promise((resolve, reject) => { const xhr = new XMLHttpRequest(); xhr.onload = function () { resolve(xhr.response); }; xhr.onerror = function (e) { reject(new TypeError("Network request failed")); }; xhr.responseType = "blob"; // 修复硬编码问题,改用入参uri xhr.open("GET", uri, true); xhr.send(null); }); }; // 上传图片到firebase storage const uploadImageToBucket = async () => { let blob; try { setUploading(true); blob = await getPictureBlob(image); const ref = await storage.ref().child(uuid.v4()); const snapshot = await ref.put(blob); console.log("link path"); return await snapshot.ref.getDownloadURL(); } catch (e) { alert(e.message); } finally { blob.close(); setUploading(false); } }; const UpdateImage = async () => { let imgUrl = await uploadImageToBucket(); if (imgUrl === null && userData.photoURL) { imgUrl = userData.photoURL; } firebase .firestore() .collection("users") .doc(firebase.auth().currentUser.uid) .update({ photoURL: imgUrl, }) .then(() => console.log("user Upadted")); }; useEffect(() => { getPermission(); }, []); useEffect(() => { getUserData(); }, []); // 新增监听image变化的副作用,选中图片后自动上传 useEffect(() => { if (image) { UpdateImage() } }, [image])
调整后用户选中图片确认后,setImage触发状态更新,就会自动执行上传逻辑,不需要额外点击上传、更新按钮。
内容的提问来源于stack exchange,提问作者houcin olmostaf
相关产品推荐
相关产品推荐

