如何使用 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") })