如何在 React(Next.js) 的 useState 中获取多个文件?

How do I get mutliple files in useState in React(Next.js)?

首先,请查看我的代码。

可能有些拼写错误! (我重写了我的代码)

const test = () => {

  const [files, setFiles] = useState([]);

  const handleFile = (e) => {
  for(let i=0; i<e.target.files.length; i++){
    setFiles([...files, e.target.files[i]
  }
}


return (


   {
   files.map((file, index) => (
       <div key={index}>
           <p>  {file[index].name}  </p>
           <button>  Delete  </button>
       </div>
   ))
   }

   <label onChange={handleFile}>
     <input type='file' mutiple /> Attach File
   </label>
)

}

当我用这段代码渲染时,出错了,

TypeError: Cannot read Properties of undefined (reading 'name')

{file[index].name}

像这样。

当我删除 .name 时,只呈现按钮。 (因为我没有指定文件 属性 的渲染内容。)

此外,我正在尝试一次渲染多个文件。当我将我的输入类型设置为多个时,我可以在选择上传内容时select多个文件。

然而,即使我 select编辑了两三个,它也只渲染了一个。

希望我的解释能很好地描述我的情况。有什么问题可以问我哦!

期待您的来信!

您不需要地图中的 [index] 部分,因此应如下所示

 <p>{file.name}</p>

现在应该可以工作了:)

多个上传的更新

  const handleFile = (e) => {
    const newSelectedArray = files;
      newSelectedArray.push({
        ...e.target.files[0],
        identifier: e.target.filename  //check this please i cant remember what the array name is called for filename. You dont need this yet but once we get the first bit working we can include it in something cool.
      });
    setFiles(newSelectedArray)
}

让我知道这个,因为这对我来说也是一场噩梦,所以希望它能奏效

对于和我有同样问题的人,这是一个权宜之计。

  const [files, setFiles] = useState([]);

     const handleFile = (e) => {
        setFiles([...files, e.target.files[0], e.target.files[1], e.target.files[2]])
        if(e.target.files[1] == null) {
            setFiles([...files, e.target.files[0]])
        } if (e.target.files[1] && e.target.files[2] == null) {
            setFiles([...files, e.target.files[0], e.target.files[1]])
        } 
    };

使用条件语句,您可以控制文件的索引。但是,我仍然不知道还有什么方法可以解决这个问题。

总之,希望我的回答对你有所帮助!

如果您在同一处理程序函数中多次更新同一状态,则只有最后一次调用才能解决性能问题。您必须将 onChange 处理程序更改为类似以下内容:

const handleFile = (e) => {
   const newFiles = []
   for(let i = 0; i < e.target.files.length; i++){
      newFiles.push(e.target.files[i])
   }
   setFiles(newFiles)
}

也如另一个答案中所述,将“名称”行更改为:

<p>{file.name}</p>

我不确定我是否遗漏了什么,但我认为像这样循环是多余的,相反你可以简单地做

const handleFile = (e) => {
   setFiles(e.target.files)
}

另外,当你想访问以前的状态值时,你应该像这样在 setFiles 中使用回调函数来访问以前的状态值

for(let i=0; i<e.target.files.length; i++){
    setFiles((prevfiles)=>[...prevFiles,e.target.files[i]])
}

编辑: 我还提到了原始答案中未包含的修复程序,因为它已经由 @Matt 在 posting.I 时声明,我编辑此答案只是为了提供完整的答案

file[index].name 必须更改为 file.name