React使用效应仅随文件上传而延迟

发布于 2025-02-11 23:23:05 字数 8360 浏览 1 评论 0原文

我的文件上传功能涉及两个组件,viewProjectAttachment以查看与项目相关的附件列表和addattachment,一种用于上传文件的表单。我的文件存储在服务器端,public/images文件夹。

viewProjectAttAthment.js

import React, {useEffect, useState, useContext} from 'react'
import Axios from 'axios';
import {Col, Row, Button, Modal, Table, Form} from 'react-bootstrap';
import {Image} from 'cloudinary-react';
import { UserContext, UserTypeContext } from './../Helper/Context';
import { useHistory } from 'react-router-dom';


function ViewProjectAttachment({itemID, isBelong}) {

    var projectId = itemID;

    const {userId, setUserId} = useContext(UserContext);
    const {type, isUserType} = useContext(UserTypeContext);

    const history = useHistory();

    const [attachmentList, setAttachmentList] = useState([]);

    const [fileSelected, setFile] = useState();

    const [showModal, setShowModal] = useState(false);
    const handleClose = () => setShowModal(false);

    const [delAttachment, setDelAttachment] = useState (false);
    const handleDelete2 = () => setDelAttachment(false);

    useEffect(()=>{
        
        Axios.get(`http://localhost:3001/${projectId}/attachment`,{
            projectId: projectId,
        })
        .then((response) => {
            
            setAttachmentList(response.data);
            
        })
    },[attachmentList]);

    const addNewAtt = () => {
        if(type === 'Staff'){
            history.push(`/staff/${userId}/addattachment/${projectId}`);
        }
        else if(type === 'Student'){
            history.push(`/student/${userId}/addattachment/${projectId}`);
        }
    }

    const deleteAttachment = (e, attachment_id) => {

        e.preventDefault();

        const attachmentId = attachment_id;

        Axios.delete(`http://localhost:3001/delattachment/${attachmentId}`, {
            attachmentId: attachmentId,
        })
        .then((respon) => {
            
            handleDelete2();
            window.alert("Attachment has been deleted!");
            
         })
    }

  return (
    <div>
            <Row>
                <Col className = "d-flex justify-content-start fw-bold">
                    Attachment
                </Col>
                <Col className = "d-flex justify-content-end">
                    <Button variant="link" onClick={addNewAtt}>+ Add</Button>
                </Col>
            <hr/>
            </Row>
            <Form>
                            
                            <Form.Group className="mb-3" controlId="image">

                                <Form.Control type="file"
                                    onChange={(event) => {
                                        setFile(event.target.files[0]);
                                    }}
                                />
                            </Form.Group>

                            
                            <div className = "d-flex flex-end justify-content-end align-items-end mt-3">
                                <div>
                                    <Button onClick={uploadImage}>Save</Button>
                                </div>
                            </div>
                        </Form>
                </Row>

                    <Modal show={showModal} onHide={handleClose}>
                        <Modal.Header closeButton>
                        <Modal.Title>SUCCESSFUL</Modal.Title>
                        </Modal.Header>
                        <Modal.Body>You have successfully uploaded an image!</Modal.Body>
                        <Modal.Footer>
                        <Button variant="secondary" onClick={handleClose}>
                            Close
                        </Button>
                        </Modal.Footer>
        
    </div>
  )
}

export default ViewProjectAttachment

addattachment.js

import React, {useState, useContext} from 'react'
import {Form, Button, Card} from 'react-bootstrap'
import Axios from 'axios';
import { useHistory } from 'react-router-dom';
import { UserContext, UserTypeContext } from './../Helper/Context';

function AddAttachment() {

    const history = useHistory();

    const {userId, setUserId} = useContext(UserContext);
    const {type, isUserType} = useContext(UserTypeContext);

    const link = window.location.pathname;
    const split = link.split("/");
    const projectId = split[4];

    const [file, setFile] = useState();
    const [fileName, setFileName] = useState("");
 
      const saveFile = (event) => {

        event.preventDefault();
        setFile(event.target.files[0]);
        setFileName(event.target.files[0].name);
      };
 
      const uploadFile = async(e, projectId) => {

        e.preventDefault();

        const formData = new FormData();
        formData.append("file", file);
        formData.append("fileName", fileName);
        formData.append("projectId", projectId);
        try {
          const res = await Axios.post(
            "http://localhost:3001/uplatt",
            formData,
          ).then((res) => {
            if(res.data.successfulAdd){

                if(type === 'Staff'){
                    window.alert('You have successfully uploaded an attachment!');
                    history.push(`/staff/${userId}/viewproject/${projectId}`);
                }
                else if(type === 'Student'){
                    window.alert('You have successfully uploaded an attachment!');
                    history.push(`/student/${userId}/viewproject/${projectId}`);
             }
            }
          });


        } catch (ex) {
          console.log(ex);
        }


      };

    const backToProject = (e) => {
        e.preventDefault();

        if(type === 'Staff'){
            history.push(`/staff/${userId}/viewproject/${projectId}`);
        }
        else if(type === 'Student'){
            history.push(`/student/${userId}/viewproject/${projectId}`);
        }
    }

  return (
    <div className="d-flex justify-content-center">
            <Card style={{ width: '70%' }}>
            <div className = "mt-3 p-5">
                <h3>
                    Add new attachment
                </h3>
                <hr/>
                <Form onSubmit={(event) => uploadFile (event, projectId)}>
                <div className="mt-1 mb-3">
                    <input type="file" name="file" onChange={(e) => saveFile(e)} />
                </div>
                <div className = "d-flex flex-end justify-content-end align-items-end mt-3">
                    <div className = "px-3">
                    <Button type="button" style={{color:'white', backgroundColor:'#104271'}} onClick={backToProject} className = "mr-3">Cancel</Button>
                    </div>
                    <div>
                    <Button type="submit" style={{color:'white', backgroundColor:'#104271'}}>Upload</Button>
                    </div>
                </div>
                </Form>
            </div>
            </Card>
        </div>
  )
}

export default AddAttachment

问题是,在将文件保存到数据库和服务器公共文件夹中后,actionmentList未更新。它花了几秒钟的时间才能显示,尽管我已经添加了attactmentlist作为我的使用效果中的依赖项数组。我的后端代码:

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(result.length > 0){
                res.send(result);
            }
        }
        )
    }
    catch(err){
        console.log(err);
    }
});

这也仅在我的上传功能中发生。其他人的工作正常。有人吗?

My file upload feature involves two components, ViewProjectAttachment to view list of attachments related to the project and AddAttachment, a form for uploading files. My files are stored in server side, public/images folder.

ViewProjectAttachment.js

import React, {useEffect, useState, useContext} from 'react'
import Axios from 'axios';
import {Col, Row, Button, Modal, Table, Form} from 'react-bootstrap';
import {Image} from 'cloudinary-react';
import { UserContext, UserTypeContext } from './../Helper/Context';
import { useHistory } from 'react-router-dom';


function ViewProjectAttachment({itemID, isBelong}) {

    var projectId = itemID;

    const {userId, setUserId} = useContext(UserContext);
    const {type, isUserType} = useContext(UserTypeContext);

    const history = useHistory();

    const [attachmentList, setAttachmentList] = useState([]);

    const [fileSelected, setFile] = useState();

    const [showModal, setShowModal] = useState(false);
    const handleClose = () => setShowModal(false);

    const [delAttachment, setDelAttachment] = useState (false);
    const handleDelete2 = () => setDelAttachment(false);

    useEffect(()=>{
        
        Axios.get(`http://localhost:3001/${projectId}/attachment`,{
            projectId: projectId,
        })
        .then((response) => {
            
            setAttachmentList(response.data);
            
        })
    },[attachmentList]);

    const addNewAtt = () => {
        if(type === 'Staff'){
            history.push(`/staff/${userId}/addattachment/${projectId}`);
        }
        else if(type === 'Student'){
            history.push(`/student/${userId}/addattachment/${projectId}`);
        }
    }

    const deleteAttachment = (e, attachment_id) => {

        e.preventDefault();

        const attachmentId = attachment_id;

        Axios.delete(`http://localhost:3001/delattachment/${attachmentId}`, {
            attachmentId: attachmentId,
        })
        .then((respon) => {
            
            handleDelete2();
            window.alert("Attachment has been deleted!");
            
         })
    }

  return (
    <div>
            <Row>
                <Col className = "d-flex justify-content-start fw-bold">
                    Attachment
                </Col>
                <Col className = "d-flex justify-content-end">
                    <Button variant="link" onClick={addNewAtt}>+ Add</Button>
                </Col>
            <hr/>
            </Row>
            <Form>
                            
                            <Form.Group className="mb-3" controlId="image">

                                <Form.Control type="file"
                                    onChange={(event) => {
                                        setFile(event.target.files[0]);
                                    }}
                                />
                            </Form.Group>

                            
                            <div className = "d-flex flex-end justify-content-end align-items-end mt-3">
                                <div>
                                    <Button onClick={uploadImage}>Save</Button>
                                </div>
                            </div>
                        </Form>
                </Row>

                    <Modal show={showModal} onHide={handleClose}>
                        <Modal.Header closeButton>
                        <Modal.Title>SUCCESSFUL</Modal.Title>
                        </Modal.Header>
                        <Modal.Body>You have successfully uploaded an image!</Modal.Body>
                        <Modal.Footer>
                        <Button variant="secondary" onClick={handleClose}>
                            Close
                        </Button>
                        </Modal.Footer>
        
    </div>
  )
}

export default ViewProjectAttachment

AddAttachment.js

import React, {useState, useContext} from 'react'
import {Form, Button, Card} from 'react-bootstrap'
import Axios from 'axios';
import { useHistory } from 'react-router-dom';
import { UserContext, UserTypeContext } from './../Helper/Context';

function AddAttachment() {

    const history = useHistory();

    const {userId, setUserId} = useContext(UserContext);
    const {type, isUserType} = useContext(UserTypeContext);

    const link = window.location.pathname;
    const split = link.split("/");
    const projectId = split[4];

    const [file, setFile] = useState();
    const [fileName, setFileName] = useState("");
 
      const saveFile = (event) => {

        event.preventDefault();
        setFile(event.target.files[0]);
        setFileName(event.target.files[0].name);
      };
 
      const uploadFile = async(e, projectId) => {

        e.preventDefault();

        const formData = new FormData();
        formData.append("file", file);
        formData.append("fileName", fileName);
        formData.append("projectId", projectId);
        try {
          const res = await Axios.post(
            "http://localhost:3001/uplatt",
            formData,
          ).then((res) => {
            if(res.data.successfulAdd){

                if(type === 'Staff'){
                    window.alert('You have successfully uploaded an attachment!');
                    history.push(`/staff/${userId}/viewproject/${projectId}`);
                }
                else if(type === 'Student'){
                    window.alert('You have successfully uploaded an attachment!');
                    history.push(`/student/${userId}/viewproject/${projectId}`);
             }
            }
          });


        } catch (ex) {
          console.log(ex);
        }


      };

    const backToProject = (e) => {
        e.preventDefault();

        if(type === 'Staff'){
            history.push(`/staff/${userId}/viewproject/${projectId}`);
        }
        else if(type === 'Student'){
            history.push(`/student/${userId}/viewproject/${projectId}`);
        }
    }

  return (
    <div className="d-flex justify-content-center">
            <Card style={{ width: '70%' }}>
            <div className = "mt-3 p-5">
                <h3>
                    Add new attachment
                </h3>
                <hr/>
                <Form onSubmit={(event) => uploadFile (event, projectId)}>
                <div className="mt-1 mb-3">
                    <input type="file" name="file" onChange={(e) => saveFile(e)} />
                </div>
                <div className = "d-flex flex-end justify-content-end align-items-end mt-3">
                    <div className = "px-3">
                    <Button type="button" style={{color:'white', backgroundColor:'#104271'}} onClick={backToProject} className = "mr-3">Cancel</Button>
                    </div>
                    <div>
                    <Button type="submit" style={{color:'white', backgroundColor:'#104271'}}>Upload</Button>
                    </div>
                </div>
                </Form>
            </div>
            </Card>
        </div>
  )
}

export default AddAttachment

Problem is, the attachmentList is not updated right after the file has been saved to database and server public folder. It took a few seconds to show, eventhough I have already added attachmentList as a dependency array in my useEffect. My back-end code:

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(result.length > 0){
                res.send(result);
            }
        }
        )
    }
    catch(err){
        console.log(err);
    }
});

This is also only happening with my upload feature. The others work just fine. Anyone?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

仅一夜美梦 2025-02-18 23:23:05

大家,这是一个非常愚蠢的错误。如果(result.length&gt; 0)在我的后端代码中。所以应该像这样:

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) => {

                res.send(result);
            }
        )
    }
    catch(err){
        console.log(err);
    }
});

You all, it was a very silly mistake. I should not have included if(result.length > 0) in my back-end code. So it should have been like this:

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) => {

                res.send(result);
            }
        )
    }
    catch(err){
        console.log(err);
    }
});

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文