如何将 setState 与另一个函数同步

How to synchronize setState with another function

下面的代码是我目前正在处理的代码。它的作用是接收一个文件作为用户输入并发送一个 axios post 请求,然后通过 Spring 引导后端,传递的文件将存储在我 PC 的 C 盘中的一个文件夹中。

import React from 'react'
import { post } from 'axios';

class SimpleFileUpload extends React.Component {

  constructor(props) {
    super(props);
    this.state ={
      file:null
    }
    this.onFormSubmit = this.onFormSubmit.bind(this)
    this.onChange = this.onChange.bind(this)
    this.fileUpload = this.fileUpload.bind(this)
  }

  onFormSubmit(e){
    e.preventDefault() // Stop form submit
    this.fileUpload(this.state.file).then((response)=>{
      console.log(response.data);
    })
  }
  onChange(e) {
    const chosenFile = e.target.files[0];
    this.setState({file:chosenFile});
  }
  fileUpload(file){
    const url = 'http://localhost:8080/report/uploadFile';
    const formData = new FormData();
    formData.append('file',file)
    const config = {
        headers: {
            'content-type': 'multipart/form-data'
        }
    }
    return  post(url, formData,config)
  }

  render() {
    return (
      <form onSubmit={this.onFormSubmit}>
        <h1>File Upload</h1>
        <input type="file" onChange={this.onChange} />
        <button type="submit">Upload</button>
      </form>
   )
  }
}

export default SimpleFileUpload

问题是 setState 是在 onChange 方法中异步执行的,当我单击 Upload 按钮触发 onFormSubmit 方法时,[= this.state 中的 18=] 是 null 并且 axios.post 请求失败。

我设法让 post 请求成功通过修改 onChange 方法,如下所示,其想法接近于使用回调函数,

onChange(e) {
  const chosenFile = e.target.files[0];
  this.setState({file:chosenFile});

  this.fileUpload(chosenFile).then((response)=>{
    console.log(response.data);
  })  
}

但是这种方式的问题是即使没有点击 Upload 按钮也会发送 post 请求。

我尝试通过添加以下两种方法来用 await 功能包装 setState

setStateSynchronous(stateUpdate){
  return new Promise(
    this.setState({file:stateUpdate})
  )
}

async callSynchSetState(stateUpdate){
  await this.setStateSynchronous(stateUpdate);
}

并修改了 onChange 方法,如下所示,但它不起作用。

onChange(e) {
  const chosenFile = e.target.files[0];
  //this.setState({file:chosenFile});
  this.callSynchSetState(chosenFile);
    
  /*this.fileUpload(chosenFile).then((response)=>{
    console.log(response.data);
  })  */
}

知道如何仅在单击 Upload 按钮时发送所选文件吗?

您对 setState 进行换行的尝试并非完全错误。你只需要写得更简洁。

而不是

setStateSynchronous(stateUpdate){
  return new Promise(
    this.setState({file:stateUpdate})
  )
}

async callSynchSetState(stateUpdate){
  await this.setStateSynchronous(stateUpdate);
}

,像这样包裹 setState

async awaitSetState(stateUpdate){
    await this.setState({file:stateUpdate})
}

,然后像这样在 onChange 方法中调用那个方法

onChange(e) {
  const chosenFile = e.target.files[0];
  this.awaitSetState(chosenFile);
}