React Native Expo安卓应用点击发布按钮时崩溃求助
React Native Expo应用添加帖子时崩溃的修复方案
问题根源分析
你的FeedScreen中触发崩溃的核心问题有以下几点:
Firestore时间戳API引用错误
代码中直接使用firestore.FieldValue.serverTimestamp(),但未正确关联已导入的firebase实例,导致变量未定义报错。Keyboard组件未导入
调用Keyboard.dismiss()但未从react-native导入Keyboard模块,引发未定义错误。未处理用户未登录的边界情况
若用户未登录,auth?.currentUser为null,此时存入Firebase的id和author会是undefined,可能触发数据写入异常。useLayoutEffect依赖缺失
useLayoutEffect中使用了navigation但未加入依赖数组,可能导致导航配置异常。
修复后的FeedScreen代码
import React, { useState, useEffect, useLayoutEffect } from 'react'; import * as firebase from 'firebase'; import { View, Text, FlatList, StyleSheet, Modal, Keyboard } from 'react-native'; // 新增Keyboard导入 import { TouchableOpacity } from 'react-native-gesture-handler'; import { auth, db } from '../firebase'; import { AntDesign, Ionicons } from '@expo/vector-icons'; import { Input, Button, Avatar } from 'react-native-elements'; const FeedScreen = ({ navigation }) => { const [posts, setPosts] = useState([]); const [addpost, setAdd] = useState(false); const [postText, setPostText] = useState(''); const likes = 0; useLayoutEffect(() => { navigation.setOptions({ headerRight: () => ( <TouchableOpacity> <AntDesign onPress={() => setAdd(true)} name="pluscircleo" size={27} color="black" /> </TouchableOpacity> ), }); }, [navigation]); // 新增navigation依赖 useEffect(() => { const unsubscribe = db .collection('posts') .orderBy('createdAt', 'desc') .onSnapshot((querySnapshot) => { const newPosts = []; querySnapshot.forEach((doc) => { newPosts.push({ id: doc.data().id, createdAt: doc.data().createdAt, text: doc.data().text, author: doc.data().author, }); }); setPosts(newPosts); }); return unsubscribe; // 新增清理函数,防止内存泄漏 }, []); const onAddButtonPress = () => { // 先判断用户是否登录 if (!auth.currentUser) { alert('请先登录'); return; } // 修正Firestore时间戳引用 const timestamp = firebase.firestore.FieldValue.serverTimestamp(); setAdd(false); const data = { createdAt: timestamp, text: postText, id: auth.currentUser.email, author: auth.currentUser.displayName || '匿名用户', // 处理displayName为空的情况 }; db .collection('posts') .add(data) .then((_doc) => { setPostText(''); Keyboard.dismiss(); }) .catch(err => { console.error('添加帖子失败:', err); // 新增错误捕获,方便排查 alert('添加帖子失败,请重试'); }); }; const postItem = ({ item, index }) => { // 处理author为空的情况,避免substr报错 const displayAuthor = item.author || '匿名用户'; return ( <View style={styles.postview}> <View style={{ borderBottomWidth: 2, borderBottomColor: '#E2E2E2', flex: 1, flexDirection: 'row', }}> <Avatar size={40} rounded title={displayAuthor.substr(0, 1)} containerStyle={{ backgroundColor: '#6733b9' }} /> <Text style={styles.autor}>{displayAuthor}</Text> </View> <View> <Text style={styles.txt}>{item.text}</Text> </View> </View> ); }; return ( <View style={{flex:1}}> {/* 新增flex:1,避免FlatList无法占满屏幕 */} <Modal visible={addpost} animationType="slide"> {/* 新增动画类型,提升体验 */} <View style={{padding:20, marginTop:40}}> <Ionicons name="close" size={40} onPress={() => setAdd(false)} /> <Text style={styles.txt2}>Add Post</Text> <View style={styles.form}> <Input placeholder="Enter post text" value={postText} onChangeText={(text) => setPostText(text)} /> <Button title="Add" onPress={onAddButtonPress} /> </View> </View> </Modal> <FlatList data={posts} renderItem={postItem} keyExtractor={(item) => item.id} style={{backgroundColor:'#E5E7E6'}} // 匹配App.js的背景色 /> </View> ); }; const styles = StyleSheet.create({ postview: { marginBottom: 10, paddingVertical: 15, // 替换'auto',因为paddingVertical不支持auto值 paddingHorizontal:10, backgroundColor: 'white', borderRadius: 30, }, autor: { fontSize: 18, marginLeft:10, marginTop: 7, }, txt: { marginTop: 20, fontSize: 17, marginHorizontal: 20, marginBottom: 20, }, txt2: { marginHorizontal: 'auto', fontSize: 40, marginTop: 20, }, form: { paddingTop: 40, // 减少padding,避免输入框太靠下 }, }); export default FeedScreen;
额外修复点说明
- 新增了useEffect的清理函数,取消Firestore快照监听,防止内存泄漏
- 处理了
author为空的情况,避免substr(0,1)报错 - 修正了
paddingVertical: 'auto'的错误,React Native的padding不支持auto值 - 新增了错误捕获和提示,方便排查添加帖子失败的原因
- 给Modal添加了动画类型,提升用户体验
内容的提问来源于stack exchange,提问作者EmikDEV
相关产品推荐
相关产品推荐

