React setState 带有回调函数并传递 props

3

我有一个文件上传组件(在 React 中编写),它通过点击处理程序触发文件上传。我想在上传过程中显示一个加载图标,因此我设置了一个 loading 状态,在调用文件处理函数时将其设置为 true。但是,在文件上传开始之前,状态更改只有时而被渲染出来,此时浏览器会冻结。因此,我搜索并发现可以将回调函数传递给 setState,该函数将在状态更改后和组件重新渲染后触发。但是,在我的情况下,我需要将从事件收集的文件传递给此回调函数……但这不起作用。我尝试过:

handleFile(files) {

    this.setState({ loading: true }, () => {
         console.log(files)
         // here is where I want to read the files
    })
}

-- 这是日志信息:文件列表 {长度:0}

handleFile(files) {

    this.setState({ loading: true }, (files) => {
         console.log(files)
         // here is where I want to read the files
    })
}

-- 这会记录未定义。

对于这个问题你有什么想法吗?顺便说一下,事件在另一个函数中处理,事件目标(文件)被传递到handleFiles函数中,问题似乎是将文件传递给回调函数。

谢谢


1
在文件上传开始之前,期间浏览器会冻结。不要同步发送文件! - Jonas Wilms
1
(files) => { 必须改为 () =>,否则你会遮蔽该标识符。 - Jonas Wilms
回调函数中,当文件数量 files.length = 0 时,我不发送任何内容 ;) 我使用FileReader来读取Excel文件,并使用XLSX解析数据。 我认为文件读取器是异步工作的... 它具有 onloadend 事件,在该事件中设置状态为 loading: false,并显示结果。 - Jimme
然后你应该找出是什么导致了你的浏览器卡死... - Jonas Wilms
是的,没错...但我认为当浏览器需要渲染上传的数据并创建一个相当大的结果表时,它实际上会冻结。 - Jimme
1个回答

0

我建议使用 Promise 来处理异步请求,像 axios 这样的库非常适合。你可以很容易地管理状态变化。例如:

handleFile(url, files) {
   this.setState({
      loading: true
   });

   axios.post(url, {
      data: files
   }).then(response => {
      this.setState({
         loading: false
      });
   })
   .catch(error => {
      console.log('Error posting data.', error);
      this.setState({
         error: true
      });   
   });
}

谢谢,但我没有进行任何HTTP请求,这是一个本地文件上传。 - Jimme

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接