React使用效应仅随文件上传而延迟
我的文件上传功能涉及两个组件,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 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
大家,这是一个非常愚蠢的错误。如果(result.length&gt; 0)在我的后端代码中。所以应该像这样:
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: