You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 16:04:55