如何使用 React Hooks 推送到动态对象中的数组?
How to push to array inside dynamic object using React Hooks?
在我编写的这段小代码中,我在设置状态并向其添加文件时创建了一个动态对象。但是,新文件会覆盖以前的文件。运气不好,我尝试在 mappedFiles
旁边的数组括号内使用扩展运算符。似乎在动态设置状态时,我无法连接或推送到 files object
.
内的数组
这是代码...
import React, { useCallback, useState, useContext } from "react";
import { ImageUploadContext } from "../../Store";
import styles from "./commentssection.module.css";
import { useDropzone } from "react-dropzone";
function ImageUploader({ title }) {
const [files, setFiles] = useContext(ImageUploadContext);
const maxSize = 5048576;
//ISSUE IS HERE. CREATING THE SETSTATE INSIDE THIS CALLBACK
const onDrop = useCallback(
(acceptedFiles) => {
const mappedFiles = acceptedFiles.map((file) =>
Object.assign(file, {
preview: URL.createObjectURL(file),
})
);
// This setstate function adds to dynamic array but doesn't return previous one. The array is being overwritten
setFiles((state) => ({ ...state, [title]: [mappedFiles] }));
},
[files]
);
const {
isDragActive,
getRootProps,
getInputProps,
isDragReject,
acceptedFiles,
rejectedFiles,
} = useDropzone({
onDrop,
accept: "image/*",
minSize: 0,
maxSize: 10000000,
});
console.log(files);
const isFileTooLarge = rejectedFiles
? rejectedFiles.length > 0 && rejectedFiles[0].size > maxSize
: null;
return (
<div>
<p>Please include comments in notes</p>
<hr className={styles["HR"]} />
<form className={styles["UploadForm"]}>
<div className={styles["UploadWrapper"]}>
<h5>Upload photos of issues found in the {title}</h5>
<section className={styles["Container"]}>
<div className={styles["ImageInput"]} {...getRootProps()}>
<input {...getInputProps()} />
{!isDragActive && "Click here or drop a file to upload!"}
{isDragActive && !isDragReject && "Drop it like it's hot!"}
{isDragReject && "File type not accepted, sorry!"}
{isFileTooLarge && (
<div className="text-danger mt-2">File is too large.</div>
)}
</div>
</section>
<div>
{files[title]
? files[title].map((object, index) =>
object.map((subObject, subIndex) => {
return (
<img
style={{ height: "80px" }}
className={styles["RenderedImage"]}
key={index}
src={subObject.preview}
/>
);
})
)
: null}
</div>
<p>
Please take a picture of any issues that you find and upload them
here. NOTE: it is only necessary to upload pictures of problems that
you find.
</p>
</div>
<div className={styles["CommentWrapper"]}>
<h5>Notes of the {title}</h5>
<textarea className={styles["Textarea"]} />
</div>
</form>
</div>
);
}
export default ImageUploader;
编辑:
多亏了 ,我才能够弄明白。以下是特定于父组件的数组代码。
const onDrop = useCallback(
(acceptedFiles) => {
const mappedFiles = acceptedFiles.map((file) =>
Object.assign(file, {
preview: URL.createObjectURL(file),
})
);
return files[title]
? setFiles((state) => ({
...state,
[title]: [...state[title], mappedFiles],
}))
: setFiles((state) => ({
...state,
[title]: [mappedFiles],
}));
},
[files, title]
);
我想我发现了问题 - 您需要在 onDrop
:
的依赖数组中包含 title
const onDrop = useCallback(
(acceptedFiles) => {
...
},
[files, title]
);
否则你 运行 有 title
过时值的风险,这会覆盖你的状态对象的 属性.
编辑:
我想这就是您要找的:
setFiles((state) => ({ ...state, [title]: [...state[title], ...mappedFiles]}));
如果您的带有数组的状态对象如下所示
var std={students:{names:["AAA","BBB","CCC"]}}
州
const[students,setstudents]=useState(std)
设置状态
setstudents({ ...students, ...students.names.push("DDD") })
在我编写的这段小代码中,我在设置状态并向其添加文件时创建了一个动态对象。但是,新文件会覆盖以前的文件。运气不好,我尝试在 mappedFiles
旁边的数组括号内使用扩展运算符。似乎在动态设置状态时,我无法连接或推送到 files object
.
这是代码...
import React, { useCallback, useState, useContext } from "react";
import { ImageUploadContext } from "../../Store";
import styles from "./commentssection.module.css";
import { useDropzone } from "react-dropzone";
function ImageUploader({ title }) {
const [files, setFiles] = useContext(ImageUploadContext);
const maxSize = 5048576;
//ISSUE IS HERE. CREATING THE SETSTATE INSIDE THIS CALLBACK
const onDrop = useCallback(
(acceptedFiles) => {
const mappedFiles = acceptedFiles.map((file) =>
Object.assign(file, {
preview: URL.createObjectURL(file),
})
);
// This setstate function adds to dynamic array but doesn't return previous one. The array is being overwritten
setFiles((state) => ({ ...state, [title]: [mappedFiles] }));
},
[files]
);
const {
isDragActive,
getRootProps,
getInputProps,
isDragReject,
acceptedFiles,
rejectedFiles,
} = useDropzone({
onDrop,
accept: "image/*",
minSize: 0,
maxSize: 10000000,
});
console.log(files);
const isFileTooLarge = rejectedFiles
? rejectedFiles.length > 0 && rejectedFiles[0].size > maxSize
: null;
return (
<div>
<p>Please include comments in notes</p>
<hr className={styles["HR"]} />
<form className={styles["UploadForm"]}>
<div className={styles["UploadWrapper"]}>
<h5>Upload photos of issues found in the {title}</h5>
<section className={styles["Container"]}>
<div className={styles["ImageInput"]} {...getRootProps()}>
<input {...getInputProps()} />
{!isDragActive && "Click here or drop a file to upload!"}
{isDragActive && !isDragReject && "Drop it like it's hot!"}
{isDragReject && "File type not accepted, sorry!"}
{isFileTooLarge && (
<div className="text-danger mt-2">File is too large.</div>
)}
</div>
</section>
<div>
{files[title]
? files[title].map((object, index) =>
object.map((subObject, subIndex) => {
return (
<img
style={{ height: "80px" }}
className={styles["RenderedImage"]}
key={index}
src={subObject.preview}
/>
);
})
)
: null}
</div>
<p>
Please take a picture of any issues that you find and upload them
here. NOTE: it is only necessary to upload pictures of problems that
you find.
</p>
</div>
<div className={styles["CommentWrapper"]}>
<h5>Notes of the {title}</h5>
<textarea className={styles["Textarea"]} />
</div>
</form>
</div>
);
}
export default ImageUploader;
编辑:
多亏了
const onDrop = useCallback(
(acceptedFiles) => {
const mappedFiles = acceptedFiles.map((file) =>
Object.assign(file, {
preview: URL.createObjectURL(file),
})
);
return files[title]
? setFiles((state) => ({
...state,
[title]: [...state[title], mappedFiles],
}))
: setFiles((state) => ({
...state,
[title]: [mappedFiles],
}));
},
[files, title]
);
我想我发现了问题 - 您需要在 onDrop
:
title
const onDrop = useCallback(
(acceptedFiles) => {
...
},
[files, title]
);
否则你 运行 有 title
过时值的风险,这会覆盖你的状态对象的 属性.
编辑:
我想这就是您要找的:
setFiles((state) => ({ ...state, [title]: [...state[title], ...mappedFiles]}));
如果您的带有数组的状态对象如下所示
var std={students:{names:["AAA","BBB","CCC"]}}
州
const[students,setstudents]=useState(std)
设置状态
setstudents({ ...students, ...students.names.push("DDD") })