【发布时间】:2021-08-17 14:56:09
【问题描述】:
我正在建立一个页面来列出产品。 所以我有一个 input:file 按钮来选择多个图像,然后我调用一个 API 将这些图像上传到服务器上,并在 UI 中显示带有图像的进度。 这是我的代码。
import axios from 'axios'
import React, { useState } from 'react'
import { nanoid } from 'nanoid'
const Demo = () => {
const [images, setImages] = useState([])
const handleImages = async (e) => {
let newArr = [...images]
for (let i = 0; i < e.target.files.length; i++) {
newArr = [
...newArr,
{
src: URL.createObjectURL(e.target.files[i]),
img: e.target.files[i],
uploaded: 0,
completed: false,
_id: nanoid(5),
},
]
}
setImages(newArr)
await uploadImages(newArr)
}
const uploadProgress = (progress, arr, idx) => {
let { total, loaded } = progress
let inPercentage = Math.ceil((loaded * 100) / total)
let imgs = [...arr]
imgs[idx]['uploaded'] = inPercentage
setImages([...imgs])
}
const uploadImages = async (imageArr) => {
for (let i = 0; i < imageArr.length; i++) {
let formData = new FormData()
formData.append('img', imageArr[i].img)
let result = await axios.post(
`http://localhost:3001/api/demo`,
formData,
{
onUploadProgress: (progress) =>
uploadProgress(progress, imageArr, i),
}
)
if (result?.data) {
let imgs = [...imageArr]
imgs[i]['completed'] = true
setImages([...imgs])
}
}
}
return (
<div>
<input
type="file"
multiple
accept="image/*"
onChange={handleImages}
/>
<div>
<div className="img-container" style={{ display: 'flex' }}>
{images.length ? (
<>
{images.map((img) => (
<div style={{ position: 'relative' }}>
<img
style={{
width: '200px',
height: 'auto',
marginRight: '10px',
}}
src={img.src}
alt="alt"
/>
{!img.completed && (
<div
style={{
background: 'rgba(0,0,0,0.3)',
padding: '4px',
position: 'absolute',
top: '10px',
left: '10px',
color: 'white',
borderRadius: '5px',
}}
>
{img.uploaded}%
</div>
)}
</div>
))}
</>
) : null}
</div>
</div>
</div>
)
}
export default Demo
由于 useState 是异步的,我不能直接将反应状态传递给我的 API 处理程序。 所以现在的问题是,假设我选择了 3 张图片来上传,并且在我的“uploadImages”函数执行完成之前,我尝试选择其他图片来上传,它没有按预期工作,我知道它没有的原因以打算的方式工作。但不知道解决办法。
问题: 假设,用户首先尝试上传 3 张图片。 “uploadImages”的第一个实例将使用参数 newArr 开始执行,该参数将有 3 个图像,我们将其设置为反应状态“图像”。 但是现在当用户尝试在第一个图像完成之前上传其他图像时,另一个“uploadImages”实例将开始执行,现在在 newArr 参数中,它将有一个新添加的图像数组,此方法将尝试设置状态“图像”。
现在我不知道该如何处理。 Preview
【问题讨论】:
标签: javascript reactjs react-hooks use-state