diff --git a/README.md b/README.md
index 440e9659..a40f79a7 100644
--- a/README.md
+++ b/README.md
@@ -15,7 +15,6 @@
English | 简体中文
-
## Highlights
- Supports Ajax uploads with progress, headers, credentials, and custom request overrides.
@@ -98,9 +97,10 @@ Then open `http://localhost:8000`.
### Methods
-| Name | Type | Description |
-| ------- | ------------------------- | ----------------------- |
-| `abort` | `(file: RcFile) => void` | Abort an active upload. |
+| Name | Type | Description |
+| ------------- | ------------------------ | ------------------------------------ |
+| `abort` | `(file: RcFile) => void` | Abort an active upload. |
+| `retryUpload` | `(file: RcFile) => void` | Retry an upload for a specific file. |
## Development
diff --git a/README.zh-CN.md b/README.zh-CN.md
index cc0e8dc8..04e23474 100644
--- a/README.zh-CN.md
+++ b/README.zh-CN.md
@@ -15,7 +15,6 @@
English | 简体中文
-
## 特性
- 支持带进度、请求头、凭证和自定义请求覆盖的 Ajax 上传。
@@ -98,9 +97,10 @@ npm start
### 方法
-| 名称 | 类型 | 说明 |
-| ------- | ------------------------- | ----------------------- |
-| `abort` | `(file: RcFile) => void` | 中止进行中的上传。 |
+| 名称 | 类型 | 说明 |
+| ------------- | ------------------------ | -------------------- |
+| `abort` | `(file: RcFile) => void` | 中止进行中的上传。 |
+| `retryUpload` | `(file: RcFile) => void` | 重试特定文件的上传。 |
## 本地开发
diff --git a/src/AjaxUploader.tsx b/src/AjaxUploader.tsx
index 0244c3be..349a75d0 100644
--- a/src/AjaxUploader.tsx
+++ b/src/AjaxUploader.tsx
@@ -301,6 +301,16 @@ class AjaxUploader extends Component {
this.reqs[uid] = request(requestOption, { defaultRequest });
}
+ retryUpload = (originFile: RcFile) => {
+ this.processFile(originFile, [originFile])
+ .then(fileInfo => {
+ if (fileInfo.parsedFile) {
+ this.post(fileInfo);
+ }
+ })
+ .catch(() => {});
+ };
+
reset() {
this.setState({
uid: getUid(),
diff --git a/src/Upload.tsx b/src/Upload.tsx
index 23541e31..6fe755ec 100644
--- a/src/Upload.tsx
+++ b/src/Upload.tsx
@@ -30,6 +30,10 @@ class Upload extends Component {
this.uploader.abort(file);
}
+ retryUpload(file: RcFile) {
+ this.uploader.retryUpload(file);
+ }
+
saveUploader = (node: AjaxUpload) => {
this.uploader = node;
};
diff --git a/tests/uploader.spec.tsx b/tests/uploader.spec.tsx
index ef835041..e73ec873 100644
--- a/tests/uploader.spec.tsx
+++ b/tests/uploader.spec.tsx
@@ -253,6 +253,57 @@ describe('uploader', () => {
}, 100);
});
+ it('retryUpload should make new request', done => {
+ const uploadRef = React.createRef();
+ render();
+
+ const file = {
+ name: 'retry.png',
+ toString() {
+ return this.name;
+ },
+ };
+ const files = [file];
+ (files as any).item = (i: number) => files[i];
+
+ const initialRequestCount = requests.length;
+
+ uploadRef.current.retryUpload(file as any);
+
+ setTimeout(() => {
+ expect(requests.length).toBe(initialRequestCount + 1);
+ done();
+ }, 100);
+ });
+
+ it('retryUpload should not make request when action rejects', done => {
+ const uploadRef = React.createRef();
+ render(
+ {
+ throw new Error('action error');
+ }}
+ />,
+ );
+
+ const file = {
+ name: 'reject.png',
+ toString() {
+ return this.name;
+ },
+ };
+
+ const initialRequestCount = requests.length;
+
+ uploadRef.current.retryUpload(file as any);
+
+ setTimeout(() => {
+ expect(requests.length).toBe(initialRequestCount);
+ done();
+ }, 100);
+ });
+
it('drag to upload', done => {
const input = uploader.container.querySelector('input')!;