admin管理员组

文章数量:1297023

I have two files - one of which is the mon file that includes the logic for PUTrequest using axios. Another file includes the ponent that has progress bar which gets updated based on the value of progressEvent from onUploadProgress method. I would like to set state for setUploadPercentage with the current value that is emitted. But I am having a hard time in refactoring my code to access this value in my class ponent FileUpload. Any help would be appreciated.

  1. File with axios request logic :-
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. File with the ponent :-
import React, { useState } from "react";
import { putData } from "../../services/clientService";
import Progress from "../mon/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;

I have two files - one of which is the mon file that includes the logic for PUTrequest using axios. Another file includes the ponent that has progress bar which gets updated based on the value of progressEvent from onUploadProgress method. I would like to set state for setUploadPercentage with the current value that is emitted. But I am having a hard time in refactoring my code to access this value in my class ponent FileUpload. Any help would be appreciated.

  1. File with axios request logic :-
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. File with the ponent :-
import React, { useState } from "react";
import { putData } from "../../services/clientService";
import Progress from "../mon/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;
Share asked May 13, 2020 at 23:05 relurelu 3531 gold badge4 silver badges20 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 5

I would pass setUploadPercentage as callback to putData and use it like that:

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);
    },
  });
}

You could pass in a callback handler into the putData method that can receive the event instead.

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

Then your ponent could be:

import React, { useState } from "react";
import { putData } from "../../services/clientService";
import Progress from "../mon/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;

Before, I make progress bar with onUploadProgress event.

this is my example code as below.

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 pleted={this.state.progress} />
        <input type="file" onChange={this.onChangeFile} />
        <button onClick={this.onUpload.bind(this)} >File Upload</button>
      </div>
    )
  }
}

I hope this will help you as well. Best Regards.

本文标签: javascriptAccessing value of progressEvent for progress bar from axios to set state in ReactStack Overflow