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

React useEffect文件上传后附件列表延迟更新问题

问题产生原因

3个核心bug叠加导致上传后列表延迟更新,删除操作不受影响:

  • 后端查询接口逻辑错误:获取附件列表的GET接口仅在查询结果result.length > 0时才返回响应,当查询结果为空时直接挂起请求不做任何返回。上传文件后存在毫秒级的数据库写入事务延迟,首次拉取列表的请求如果在事务提交前到达后端,会拿到空结果,请求就会一直挂起,直到后续请求查到非空结果才会响应;而删除操作后列表始终存在至少0条以上记录,只要项目下还有附件,查询结果的length就大于0,接口会正常返回,不会挂起。
  • 前端useEffect依赖配置完全错误:将attachmentList自身作为useEffect的依赖项,会触发无限循环请求——每次请求完成调用setAttachmentList更新状态,状态变化又触发useEffect重新执行发请求,这种无意义的轮询不仅浪费性能,还刚好撞上了后端接口空结果不返回的问题,要等好几轮轮询才能拿到插入完成后的非空结果,造成数秒延迟。
  • 缺少操作完成后的主动刷新逻辑:删除、上传这类修改数据的操作完成后,没有主动触发列表重新拉取,完全依赖useEffect的被动触发,本身就不符合数据更新的交互逻辑。

另外你的Axios传参写法也有问题:Axios.get的第二个参数是请求配置项,query参数需要放在params字段下,你当前直接传对象的写法不会把参数带到请求里,只是因为你用了路径参数传projectId才没有报错。

可行修复方案

按顺序修复前后端问题即可解决延迟:

1. 修复后端查询接口逻辑

无论查询结果是否为空都正常返回响应,不要挂起请求,修正后的代码如下:

app.get("/:projectId/attachment", function(req, res){
    const projectId = req.params.projectId;
    try{
        const findProjectAttachment = "SELECT project_attachment.project_attachment_id, project_attachment.project_attachment_url, project_attachment.project_id FROM project_attachment INNER JOIN project ON project_attachment.project_id=project.project_id WHERE project_attachment.project_id = ?;";
        db.query(findProjectAttachment, projectId, (err, result) => {
            if(err){
                console.log(err);
                return res.status(500).send({error: "查询附件失败"});
            }
            // 空数组也正常返回,不要判断length
            res.send(result);
        })
    }
    catch(err){
        console.log(err);
        res.status(500).send({error: "服务异常"});
    }
});

同时建议检查你的文件上传接口(/uplatt),确保文件写入磁盘、数据库插入记录都完成后再给前端返回成功响应,不要提前返回造成前端跳转时数据还没写入完成。

2. 修复前端useEffect的错误依赖

把拉取附件列表的逻辑抽成独立方法,仅在组件挂载、关联项目ID变化时触发请求,去掉会造成死循环的attachmentList依赖:

// 抽离独立的拉取方法,方便各处主动调用
const fetchAttachmentList = () => {
    Axios.get(`http://localhost:3001/${projectId}/attachment`)
    .then((response) => {
        setAttachmentList(response.data);
    })
    .catch(err => console.error("获取附件列表失败", err))
}

useEffect(()=>{
    fetchAttachmentList();
    // 仅依赖projectId,不要依赖attachmentList
},[projectId]);

3. 增加操作完成后的主动刷新

在删除附件、上传附件这类修改操作完成后,主动调用fetchAttachmentList()拉取最新数据,不需要等轮询:

  • 修复删除逻辑,删除成功后直接刷新列表:
const deleteAttachment = (e, attachment_id) => {
    e.preventDefault();
    const attachmentId = attachment_id;
    Axios.delete(`http://localhost:3001/delattachment/${attachmentId}`, {
        params: {attachmentId: attachmentId}
    })
    .then((respon) => {
        window.alert("Attachment has been deleted!");
        // 主动刷新列表
        fetchAttachmentList();
        handleDelete2();
    })
    .catch(err => console.error("删除失败", err))
}
  • 上传附件的场景,从AddAttachment页面跳回列表页时,组件如果没有重新挂载,可以通过react-router的路由状态、或者全局状态触发一次fetchAttachmentList调用即可,不需要保留无限轮询的逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 20:45:32