使用 Redux-Thunk / Axios 从 onUploadProgress 事件调度操作

Posted

技术标签:

【中文标题】使用 Redux-Thunk / Axios 从 onUploadProgress 事件调度操作【英文标题】:Dispatching action from onUploadProgress event using Redux-Thunk / Axios 【发布时间】:2018-09-07 09:27:46 【问题描述】:

以下代码上传文件没有问题,并按预期成功或失败响应,但是,我无法弄清楚如何从onUploadProgress 事件中调度我的uploadFileProgress 操作。我可以console.log 进度/百分比,当我尝试将调度包装在 IIFE 中时,我触发调度不是函数错误。希望这是我错过的一个小问题。提前致谢!

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】:

将您的请求配置移到返回的函数中(dispatch 函数将可以访问):

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

onUploadProgress 也应该只是 dipatch 上传进度事件。

【讨论】:

谢谢@Tomasz!我希望解决方案很简单。确实,onUploadProgress 确实调度了上传进度事件,但我需要捕获该事件,并在后处理后将其调度到我的减速器:-)【参考方案2】:

我无法完全修复您的代码,但这是一个基本功能,redux-thunk 执行异步操作并使用操作。

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

当然 redux-thunk 必须作为中间件添加。

【讨论】:

【参考方案3】:

你为什么要从 onUploadProgress 函数返回一个函数

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

你可以这样做

dispatch(uploadFileUpload(progressData));

【讨论】:

以上是关于使用 Redux-Thunk / Axios 从 onUploadProgress 事件调度操作的主要内容,如果未能解决你的问题,请参考以下文章

使用 axios 和 redux-thunk 以 redux-form 发布请求

如何使用“redux-thunk”调用 ajax?

Redux axios 请求取消

取消路由更改请求 (React/Redux/Axios)

Redux Thunk操作,axios返回多个值

使用 Redux Thunk 和 Axios 测试 Action Creator