从 axios 访问进度条的 progressEvent 值以在 React 中设置状态

Accessing value of progressEvent for progress bar from axios to set state in React

我有两个文件 - 其中一个是包含使用 axios 的 PUT 请求逻辑的通用文件。另一个文件包含具有 progress bar 的组件,该组件根据 onUploadProgress 方法的 progressEvent 的值进行更新。我想用发出的当前值设置 setUploadPercentage 的状态。但是我很难重构我的代码以在我的 class 组件 FileUpload 中访问这个值。任何帮助,将不胜感激。

  1. 具有 axios 请求逻辑的文件:-
export function putData(formData) {
  return axios.put('/update', formData, {
    headers: {
      "Content-Type": "multipart/form-data",
    },
    onUploadProgress : (progressEvent) => {
        return parseInt(Math.round((progressEvent.loaded * 100) / progressEvent.total))
    },
  });
}
  1. 包含组件的文件:-
import React, { useState } from "react";
import { putData } from "../../services/clientService";
import Progress from "../common/progress";

const FileUpload = () => {
  const [uploadPercentage, setUploadPercentage] = useState(0);

  const onChange = (e) => {
    setFile(e.target.files[0]);
    setFilename(e.target.files[0].name);
  };

  const onSubmit = async (e) => {
    e.preventDefault();
    const formData = new FormData();
    formData.append("file", file);
    // trying to use progressEvent value to update the value of uploadPercentage from response
    const res = await putData(formData);
  };

  return <Progress percentage={uploadPercentage} />;
};

export default FileUpload;

您可以将回调处理程序传递给可以接收事件的 putData 方法。

export function putData(formData, handleUploadProgress = ()=>{}) {
  return axios.put('/update', formData, {
    headers: {
      "Content-Type": "multipart/form-data",
    },
    onUploadProgress : handleUploadProgress,
  });
}

那么你的组件可能是:

import React, { useState } from "react";
import { putData } from "../../services/clientService";
import Progress from "../common/progress";

const FileUpload = () => {
  const [uploadPercentage, setUploadPercentage] = useState(0);

  const onChange = (e) => {
    setFile(e.target.files[0]);
    setFilename(e.target.files[0].name);
  };

  const onSubmit = async (e) => {
    e.preventDefault();
    const formData = new FormData();
    formData.append("file", file);
      // trying to use progressEvent value to update the value of uploadPercentage from response
      /* I think you need to remove this line for the rendering to progress, but maybe not.
        const res = await putData(formData);
      */ 
    putData(formData, (progressEvent) => {
      const percentage= parseInt(Math.round((progressEvent.loaded * 100) / progressEvent.total));
      setUploadPercentage(percentage);
      return percentage; // Because you were returning the percentage before.
    });
  };

  return <Progress percentage={uploadPercentage} />;
};

export default FileUpload;

我会将 setUploadPercentage 作为回调传递给 putData 并像这样使用它:

const onSubmit = (e) => {
  e.preventDefault();
  const formData = new FormData();
  formData.append("file", file);

  // Pass a setUploadPercentage as callback here
  putData(formData, { onUploadProgress: setUploadPercentage )
    .then((response) => { 
      console.log(response);
    });
};
export function putData(formData, { onUploadProgress }) {
  return axios.put('/update', formData, {
    headers: {
      "Content-Type": "multipart/form-data",
    },
    onUploadProgress : (progressEvent) => {
      const progress = parseInt(Math.round((progressEvent.loaded * 100) / progressEvent.total));
      // Update state here
      onUploadProgress(progress);
    },
  });
}

之前,我用 onUploadProgress 事件制作进度条。

这是我的示例代码,如下所示。

import React from 'react';
import Progress from 'react-progressbar';
import axios from 'axios';
export default class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      progress: 0,
      uploadFile: null,
    }
  }
  onChangeFile = (event) => {
    this.setState({ uploadFile: event.target.files[0] })
  }

  onUpload = () => {
    const config = {
      onUploadProgress: progressEvent => {
        let { progress } = this.state;
        progress = (progressEvent.loaded / progressEvent.total) * 100;
        this.setState({ progress });
      }
    }

    let formData = new FormData();
    formData.append("file", this.state.uploadFile);
    axios.post('http://your_backend_url/api/v1/upload', formData, config).then(res => {
      if (res.data.status == 200) {
        console.log("done: ", res.data.message);
      }
    }).catch(err => {
      console.log("error: ", err.message);
    })
  }

  render() {
    return (
      <div className="App">
        <Progress completed={this.state.progress} />
        <input type="file" onChange={this.onChangeFile} />
        <button onClick={this.onUpload.bind(this)} >File Upload</button>
      </div>
    )
  }
}

希望这对您也有帮助。 最好的问候。