React Native组件仅显示首个投诉,新增投诉无法加载求助
问题:React Native页面仅显示第一个投诉,新增投诉无法展示
我正在开发一个React Native页面,该页面跳转时接收上个页面的路由参数,但目前仅能显示第一个投诉,新增的投诉始终无法展示。以下是我的代码:
const ECScreen = ({ route, navigation }) => { const { imageUri, complaintDate, complaintId } = route.params; const [complaints, setComplaints] = useState([]); // Function to add a new complaint to the complaints state const addNewComplaint = (newComplaint) => { setComplaints((prevComplaints) => [...prevComplaints, newComplaint]); }; useEffect(() => { if (imageUri && complaintDate) { const newComplaint = { id: complaints.length + 1, imageUri: imageUri, date: complaintDate, status: 'Pending', }; addNewComplaint(newComplaint); } }, [imageUri, complaintDate]); useEffect(() => { const verifyImage = async () => { const formData = new FormData(); formData.append('imagefile', { uri: imageUri, type: 'image/jpeg', // Replace with the appropriate image type name: 'image.jpg', }); try { const response = await fetch('http://10.0.2.2:5000/', { method: 'POST', body: formData, }); const data = await response.text(); console.log('Received value text:', data); if (data === 'Garbage') { // Update the complaint status based on the response setComplaints((prevComplaints) => { return prevComplaints.map((complaint) => complaint.imageUri === imageUri ? { ...complaint, status: 'Verified' } : complaint ); }); } else { // Image is not garbage, set status to 'Invalid' setComplaints((prevComplaints) => { return prevComplaints.map((complaint) => complaint.imageUri === imageUri ? { ...complaint, status: 'Invalid' } : complaint ); }); } } catch (error) { console.error('Error sending request to Flask:', error); } }; if (imageUri) { verifyImage(); } }, [imageUri]); const handleDeleteButtonPress = (id) => { // Remove the complaint with the given ID const updatedComplaints = complaints.filter((complaint) => complaint.id !== id); setComplaints(updatedComplaints); navigation.navigate('Manage Complaint Screen', { imageUri: null, // Set imageUri to null complaintDate: complaint.date, complaintId: id, complaints: updatedComplaints, }); }; const complaint = complaints.find((complaint) => complaint.imageUri === imageUri); return ( <View style={styles.container}> {complaints.length > 0 ? ( complaints.map((complaint) => ( <View key={complaint.id} style={styles.complaintContainer}> {complaint.imageUri ? ( <Image source={{ uri: complaint.imageUri }} style={styles.image} /> ) : ( <Image source={{ uri: 'https://media.istockphoto.com/id/1198347486/vector/photo-camera-vector-icon-with-hand-drawn-doodle-style-isolated-on-white.jpg?s=170667a&w=0&k=20&c=bfrS3E5e29kK33aRkVMN3-RdAOD7g9JvFEG52_vOfZ8=', }} style={styles.image} /> )} <View style={styles.textContainer}> <Text style={styles.dateText}>Date: {complaint.date}</Text> <Text style={styles.statusText}>Status: {complaint.status}</Text> </View> <TouchableOpacity style={styles.deleteButton} onPress={() => handleDeleteButtonPress(complaint.id)} > <Text style={styles.icon}>x</Text> </TouchableOpacity> </View> )) ) : ( <Text style={styles.noComplaintsText}>No complaints registered</Text> )} <TouchableOpacity style={styles.addButton} onPress={() => navigation.navigate('Register Complaint Screen') } > <Text style={styles.addButtonText}>+</Text> </TouchableOpacity> </View> ); };
我是React Native新手,代码是分段编写后整合的,无法定位问题所在,恳请帮忙排查解决。
核心问题排查与修复方案
1. 投诉ID生成逻辑缺陷
当前用complaints.length + 1生成ID,删除投诉后数组长度变小,会导致新增投诉ID重复,React列表渲染时key重复会阻止组件更新。
修复:
改用时间戳生成唯一ID:
id: Date.now(),
2. 路由参数重复添加投诉
从注册页面返回时,若参数未变化或组件未感知参数更新,会导致重复添加或不添加新投诉。同时第一个useEffect缺少complaints依赖,无法正确判断是否已存在该投诉。
修复:
useEffect(() => { if (imageUri && complaintDate) { // 避免重复添加相同图片的投诉 const isDuplicate = complaints.some(c => c.imageUri === imageUri); if (!isDuplicate) { const newComplaint = { id: Date.now(), imageUri: imageUri, date: complaintDate, status: 'Pending', }; addNewComplaint(newComplaint); } } }, [imageUri, complaintDate, complaints]); // 添加complaints到依赖数组
3. 组件挂载时状态丢失
每次跳转回该页面,组件若重新挂载,complaints状态会重置为空数组,之前的投诉全部丢失。
修复(可选):
用AsyncStorage持久化状态:
import AsyncStorage from '@react-native-async-storage/async-storage'; // 组件挂载时加载保存的投诉数据 useEffect(() => { const loadComplaints = async () => { const savedData = await AsyncStorage.getItem('complaints'); if (savedData) setComplaints(JSON.parse(savedData)); }; loadComplaints(); }, []); // 状态更新时保存到本地 useEffect(() => { AsyncStorage.setItem('complaints', JSON.stringify(complaints)); }, [complaints]);
4. 删除按钮参数错误
handleDeleteButtonPress中complaint.date未定义,需传递当前点击投诉的日期。
修复:
const handleDeleteButtonPress = (id, date) => { const updatedComplaints = complaints.filter(c => c.id !== id); setComplaints(updatedComplaints); navigation.navigate('Manage Complaint Screen', { imageUri: null, complaintDate: date, complaintId: id, complaints: updatedComplaints, }); }; // 调用时传递date参数 <TouchableOpacity style={styles.deleteButton} onPress={() => handleDeleteButtonPress(complaint.id, complaint.date)} > <Text style={styles.icon}>x</Text> </TouchableOpacity>
5. 图片重复验证
verifyImage的useEffect缺少complaints依赖,会重复验证同一图片,且无法判断投诉是否已验证。
修复:
useEffect(() => { const verifyImage = async () => { const targetComplaint = complaints.find(c => c.imageUri === imageUri); // 已验证过的投诉不再重复请求 if (targetComplaint && targetComplaint.status !== 'Pending') return; // 原图片验证逻辑... }; if (imageUri) verifyImage(); }, [imageUri, complaints]); // 添加complaints到依赖数组
内容的提问来源于stack exchange,提问作者Crdnpyaad
相关产品推荐
相关产品推荐

