[英]How to add a value to an object inside a array of files?
I am trying to add a key-value pair to an array of files.我正在尝试将键值对添加到文件数组中。 I know that this question is already covered in detail in other articles, eg here .
我知道这个问题已经在其他文章中详细介绍过,例如这里。 However, the approaches used do not work in my context.
但是,所使用的方法在我的上下文中不起作用。 If I missed something or there is another obvious flaw, please apologize!
如果我遗漏了什么或有另一个明显的缺陷,请道歉!
I have one or more pictures in an array and would like to add the information to each of these files, whether the picture is a title image or not.我在一个数组中有一张或多张图片,并希望将信息添加到每个文件中,无论图片是否为标题图像。 Ie I want to achieve something like this:
即我想实现这样的事情:
[0: {File: {name: "Test",
lastModified: "125344",
etc: "something"},
isTitlePicture: null}
1: {File: {name: "Test",
lastModified: "125344",
etc: "something"},
isTitlePicture: null}]
With my current code I get the array as as displayed below.使用我当前的代码,我得到如下所示的数组。 This means that the information about the title image is inside the file information.
这意味着有关标题图像的信息在文件信息中。 This is what I try to avoid.
这是我试图避免的。
[0: File: {name: "Test",
lastModified: "125344",
etc: "someting",
isTitlePicture: {isTitlePicture: null}}
1: File: {name: "Test",
lastModified: "125344",
etc: "someting",
isTitlePicture: {isTitlePicture: null}]
import React, { Component } from "react";
import { MDBRow, MDBCol, MDBCardBody, MDBCard, MDBCardImage } from "mdbreact";
export class ImageUploadView extends Component {
constructor(props) {
super(props);
this.state = {
files: [],
images: []
};
}
onChangeImage(e) {
const files = Array.from(e.target.files);
var obj = { isTitlePicture: null };
files.forEach(item => item.isTitlePicture = {...obj});
const images = files.map((file) => URL.createObjectURL(file));
this.setState({
files: [...this.state.files, ...files],
images: [...this.state.images, ...images]
});
}
render() {
return (
<React.Fragment>
<div className="card card-body mt-4 mb-4">
<h1>Add Image</h1>
<div>
<input
type="file"
onChange={(e) => this.onChangeImage(e)}
multiple
//accept=".jpg,.png"
/>
</div>
<div className="Images">
{this.state.images.map((image, i) => (
<MDBRow
key={image}
style={{ margin: "10px", display: "inline-block" }}
>
<MDBCol>
<MDBCard style={{ width: "5rem" }}>
<MDBCardImage
className="img-fluid"
src={image}
waves
/>
<MDBCardBody>
</MDBCardBody>
</MDBCard>
</MDBCol>
</MDBRow>
))}
</div>
</div>
</React.Fragment>
);
}
}
}
Basically I want to have isTitlePicture on the same "level" as File and not within File.基本上我想让 isTitlePicture 与 File 处于同一“级别”,而不是在 File 中。
You can simplify your code a little bit like this:您可以像这样简化代码:
onChangeImage(e) {
// Use spread operator like you do everywhere else.
const files = [...e.target.files].map(file => ({
isTitlePicture: null,
file // same as file: file,
}));
const images = files.map(
({file}) => URL.createObjectURL(file)
);
// When dealing with previous state, the best practice is to pass a
// function to setState that'll give you access to your mmm... prev state
// Read below...
this.setState(prevState => ({
files: [...prevState.files, ...files],
images: [...prevState.images, ...images],
}));
}
The code above will make your state look like:上面的代码将使您的状态看起来像:
"files": [
{
"isTitlePicture": null,
"file": {File Object}
},
{
"isTitlePicture": null,
"file": {File Object}
}
],
"images": [
"blob:https://...",
"blob:https://..."
]
}
setState
is async, that's why it is better to pass a function when dealing with old state: https://reactjs.org/docs/state-and-lifecycle.html#state-updates-may-be-asynchronous setState
是异步的,这就是为什么在处理旧状态时最好传递一个函数: https : //reactjs.org/docs/state-and-lifecycle.html#state-updates-may-be-asynchronous
Also, make sure you call URL.revokeObjectURL(file)
once you're done with the files.此外,请确保在完成
URL.revokeObjectURL(file)
调用URL.revokeObjectURL(file)
。 The browser does not release the reference to your files until you manually do it and can cause a memory leak in a single page app.在您手动执行之前,浏览器不会释放对您的文件的引用,这可能会导致单页应用程序中的内存泄漏。
I don't have enough context, but looks like you could include the File URL as part of your files
array:我没有足够的上下文,但看起来您可以将文件 URL 作为
files
数组的一部分:
const files = [...e.target.files].map(file => ({
isTitlePicture: null,
file,
url: URL.createObjectURL(file),
}));
Good luck!祝你好运!
Victor胜利者
I think your object structure is wrong.我认为你的对象结构是错误的。
onChangeImage(e) {
const files = Array.from(e.target.files);
var result = [];
files.forEach(item => result.push({file:item,isTitlePicture: null}));
const images = result.map((file) => URL.createObjectURL(file));
this.setState({
files: [...this.state.files, ...result],
images: [...this.state.images, ...images]
});
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.