Dispatching action from onUploadProgress event using Redux-Thunk / Axios

允我心安 提交于 2019-12-14 02:17:42

问题


The following code uploads a file no problem and responds successfully or failing as expected, however, I cannot figure out how to dispatch my uploadFileProgress action from the onUploadProgress event. I can console.log the progress / percentage and when I try to wrap the dispatch in an IIFE, I trigger a dispatch is not a function error. Hopefully this is a small issue I'm missing. Thanks in advance!

export function uploadFile(values, callback = () => {}) {
  const uploadFileData = new FormData();
  uploadFileData.append('fileName', values.fileName);
  uploadFileData.append('file', values.file);
  uploadFileData.append('file', {
    filename: values.filename,
    contentType: values.contentType,
  });
  const uploadProgress = {
    onUploadProgress: (ProgressEvent) => {
      let progressData = 0;
      const totalLength = ProgressEvent.lengthComputable ? ProgressEvent.total : ProgressEvent.target.getResponseHeader('content-length') || ProgressEvent.target.getResponseHeader('x-decompressed-content-length');
      if (totalLength !== null) {
        progressData = Math.round((ProgressEvent.loaded * 100) / totalLength);
      }
      return function action(dispatch) {
        dispatch(uploadFileUpload(progressData));
      };
    },
  };
  const configPlusProgress = Object.assign(uploadProgress, config);
  const request = () => axios.post(myURL, uploadFileData, configPlusProgress);
  return function action(dispatch) {
    dispatch(uploadFileLoading(true));
    return request()
      .then((response) => {
        if (response.status !== 201) {
          dispatch(uploadFileFail());
          throw Error(response.statusText);
        }
        dispatch(uploadFileLoading(false));
        return response;
      })
      .then(response => dispatch(uploadFileSuccess(response)))
      .then(() => callback())
      .catch(err => dispatch(uploadFileFail(err)));
  };
}

回答1:


move your request config inside returned function (where dispatch function will be accessible):

export function uploadFile(values, callback = () => {}) {
  const uploadFileData = new FormData();
  uploadFileData.append('fileName', values.fileName);
  uploadFileData.append('file', values.file);
  uploadFileData.append('file', {
    filename: values.filename,
    contentType: values.contentType,
  });
  return function action(dispatch) {
    const uploadProgress = {
      onUploadProgress: (ProgressEvent) => {
        let progressData = 0;
        const totalLength = ProgressEvent.lengthComputable ? ProgressEvent.total : ProgressEvent.target.getResponseHeader('content-length') || ProgressEvent.target.getResponseHeader('x-decompressed-content-length');
        if (totalLength !== null) {
          progressData = Math.round((ProgressEvent.loaded * 100) / totalLength);
        }

        dispatch(uploadFileUpload(progressData));
      },
    };
    const configPlusProgress = Object.assign(uploadProgress, config);
    const request = () => axios.post(myURL, uploadFileData, configPlusProgress);

    dispatch(uploadFileLoading(true));
    return request()
      .then((response) => {
        if (response.status !== 201) {
          dispatch(uploadFileFail());
          throw Error(response.statusText);
        }
        dispatch(uploadFileLoading(false));
        return response;
      })
      .then(response => dispatch(uploadFileSuccess(response)))
      .then(() => callback())
      .catch(err => dispatch(uploadFileFail(err)));
  };
}

Also onUploadProgress should just dipatch upload progress event.




回答2:


I can't quite fix your code but here is a basic function with redux-thunk doing async stuff and using actions.

const doSomeAsyncStuff = () =>
    async ( dispatch ) => {
         try {
             const response = await someAsyncStuff();
             return dispatch( someSuccessAction( response.data );
         } catch ( error ) {
             return dispatch( someFailureAction( err );
         }
    }

Of course redux-thunk must be added as a middleware.




回答3:


why are you returning a function from onUploadProgress function

return function action(dispatch) {
    dispatch(uploadFileUpload(progressData));
  };

Instead of that you can just

dispatch(uploadFileUpload(progressData));


来源:https://stackoverflow.com/questions/49538835/dispatching-action-from-onuploadprogress-event-using-redux-thunk-axios

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!