为什么 JavaScript 展开符号在这里不起作用

Why is the JavaScript spread notation not working here

我正在学习 React,但有一个我无法解决的简单问题。

我创建了一个Codesandbox

图中:file 是一个键值数组,如图所示。

下面这段代码后有运行:

return { ...file, md5: SHA256(fileContents).toString() };

那么结果就是键值对被移除了,如图所示:

如您所见,该文件现在仅包含 pathmd5,其他所有内容均已消失。

我知道这可能与浅拷贝原则有关,但我已经在寻找解决方案但无法理解如何解决这个问题。

const FilePicker = ({ setNewFileForValidation }) => {
    const readFileContents = async file => {
        return new Promise((resolve, reject) => {
            const fileReader = new FileReader();
            fileReader.onload = () => {
                resolve(fileReader.result);
            };
            fileReader.onerror = reject;
            fileReader.readAsBinaryString(file);
        });
    };
    const readAllFiles = async AllFiles => {
        const results = await Promise.all(
            AllFiles.map(async file => {
                const fileContents = await readFileContents(file);
                return { ...file, md5: SHA256(fileContents).toString() };
            }),
        );
        console.log(results, 'resutls');
        return results;
    };

    function onDrop(acceptedFiles, rejectedFiles) {
        readAllFiles(acceptedFiles).then(result => {
            setNewFileForValidation(result);
        });
    }
    return <Dropzone onDrop={onDrop} />;
};

file 来自 react-dropzone 并包含文件选择器的结果。也许这就是这个传播副本不起作用的原因?

也许你可以把 map 变成 for。

readAllFiles = async (AllFiles) => {
  let results = [];
  for (let file of AllFiles) {
    const fileContents = await this.readFileContents(file);
    results.push({ file, md5: SHA256(fileContents).toString() });
  }

  console.log(results, "result");
  return results;
};

文件是一个特殊的对象,其属性不可枚举。因此传播语法没有按预期工作。您需要 使用 File 构造函数。

readAllFiles = async (AllFiles) => {
    const results = await Promise.all(
      AllFiles.map(async (file) => {
        const fileContents = await this.readFileContents(file);
        // THIS IS THE PROBLEM
        //return { ...file, md5: SHA256(fileContents).toString() };
        file = new File([file], file.name, { type: file.type })
        file.md5 = SHA256(fileContents).toString();
        return file;
      })
    );
    console.log(results, "result");
    return results;
  };

您可以使用 Object.assign 而不是扩展语法,因此而不是:

{ ...file, md5: SHA256(fileContents).toString() };

使用这个:

Object.assign(file, { md5: SHA256(fileContents).toString() });