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

发布新反馈后如何更新评论列表?React Native代码问题排查

问题分析与修复

你的代码里有一个关键错误导致评论列表不更新:把useEffect误写成了useState,用来监听refresh状态并重新获取评论的逻辑根本没有执行,所以即使更新了refresh,也不会触发API重新请求,自然看不到新评论。

具体修复步骤

  1. 替换错误的useState为useEffect
    你原本想通过refresh状态变化触发重新获取评论,但误用了useState钩子,正确应该用useEffect。

  2. 优化状态更新方式
    在handleSubmit里更新refresh时,使用函数式更新setRefresh(prev => prev + 1),避免异步状态更新带来的数值错误。

  3. 可选:提交成功后直接更新本地列表(无需重新请求API)
    如果你的POST接口返回了新创建的评论数据,可以直接把它添加到responseData中,这样更高效,不用再次调用GET接口。

修复后的完整代码

import { useNavigation } from '@react-navigation/native';
import React, { useEffect, useState } from 'react';
import {
    StyleSheet,
    View,
    Text,
    Image,
    ScrollView,
    TouchableOpacity,
    Modal,
    TextInput,
    Alert,
} from 'react-native';
import { Button, Paragraph, Wrapper } from '../components';
import { baseStyle, images, theme, routes } from '../config';
import axios from 'axios';
import { useContext } from 'react';
import { AuthContext } from '../context/AuthContext';

export const Reviews = ({ route }) => {
    const { userInfo } = useContext(AuthContext);
    const navigation = useNavigation();

    const [isModalVisible, setisModalVisible] = useState(false);
    const { item } = route.params;
    const [responseData, setResponseData] = useState([]);
    const [text, setText] = useState('');
    const [refresh, setRefresh] = useState(0);

    const handleSubmit = async () => {
        console.log('Submitted Feedback: ', text);
        if (text.trim() === '') {
            Alert.alert('Error', 'Feedback cannot be blank');
            return;
        }
        try {
            const res = await axios.post(`https://514c-119-157-87-212.ngrok-free.app/listing/${item.id}/feedback`, {
                feedback: text, token: userInfo.data
            });
            const FeedbackInfo = res.data;
            // 方式1:直接添加新评论到本地列表(如果接口返回了新评论的完整数据)
            if (FeedbackInfo.data) {
                setResponseData(prev => [FeedbackInfo.data, ...prev]);
            } else {
                // 方式2:触发refresh重新拉取所有评论
                setRefresh(prev => prev + 1);
            }
            Alert.alert('Success', FeedbackInfo.message);
            setText(''); // 清空输入框
            setisModalVisible(false);
        } catch (e) {
            console.log(`feedback error ${e}`);
        }
    }

    // 修正:使用useEffect监听refresh变化
    useEffect(() => {
        const fetchReviews = async () => {
            try {
                const response = await axios.get(`https://514c-119-157-87-212.ngrok-free.app/listing/${item.id}/feedback`);
                setResponseData(response.data.data);
            } catch (error) {
                console.log(error);
            }
        };
        fetchReviews();
    }, [refresh, item.id]);

    return (
        <Wrapper>
            <View style={styles.header}>
                <TouchableOpacity onPress={() => navigation.goBack()}>
                    <Image source={images.back} style={styles.backIcon} />
                </TouchableOpacity>
                <Text style={styles.headerText}> Reviews </Text>
            </View>
            <ScrollView showsVerticalScrollIndicator={false} style={styles.review}>
                {responseData.length > 0 ?
                    responseData.map((reviewItem) => (
                        <View key={reviewItem.id} style={styles.reviewContainer}>
                            <View style={styles.flex}>
                                <Paragraph style={styles.reviewer}> {reviewItem.name} </Paragraph>
                            </View>
                            <Paragraph>
                                {reviewItem.feedback_desc}
                            </Paragraph>
                        </View>
                    ))
                    :
                    <Text>No reviews yet, be the first to comment!</Text>
                }
            </ScrollView>
            <View style={styles.footer}>
                <TouchableOpacity>
                    <Button onPress={() => {
                        if (userInfo.data) setisModalVisible(true);
                        else navigation.navigate(routes.LOGIN, { item: item });
                    }}> Post a review </Button>
                </TouchableOpacity>
            </View>
            <Modal
                transparent={true}
                animationType='slide'
                visible={isModalVisible}
            >
                <View style={styles.modalContainer}>
                    <TextInput
                        label="Review"
                        multiline={true}
                        mode="outlined"
                        activeOutlineColor={theme.colors.blue}
                        style={{ height: 100, marginBottom: 20 }} // 调整高度方便输入多行
                        placeholder="Type here to enter a feedback"
                        onChangeText={newText => setText(newText)}
                        value={text}
                    />
                    <View style={{ ...styles.modalButtonContainer, width: '70%' }}>
                        <Button onPress={handleSubmit}> Submit </Button>
                        <Button onPress={() => {
                            setisModalVisible(false);
                            setText(''); // 关闭时清空输入
                        }}> Close </Button>
                    </View>
                </View>
            </Modal>
        </Wrapper>
    );
};

关于实时更新方案的说明

  • 你提到的Pusher是实时推送方案,适合需要即时显示其他用户评论的场景,不需要依赖用户手动操作或刷新。如果你的应用需要多人实时互动,这种方案更优。
  • 而上面的修复是主动拉取方案,适合单用户提交后更新自己的视图,实现简单,不需要额外的后端配置。

内容的提问来源于stack exchange,提问作者ctr1L

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 12:52:55