mirror of
https://github.com/ant-design/ant-design.git
synced 2024-11-28 05:05:48 +08:00
fix: Upload in React 18 sync problem (#41082)
* fix: Upload in React 18 sync problem * test: add test case
This commit is contained in:
parent
55166d4272
commit
c38108a63c
@ -116,7 +116,9 @@ const InternalUpload: React.ForwardRefRenderFunction<unknown, UploadProps> = (pr
|
|||||||
changeInfo.event = event;
|
changeInfo.event = event;
|
||||||
}
|
}
|
||||||
|
|
||||||
onChange?.(changeInfo);
|
flushSync(() => {
|
||||||
|
onChange?.(changeInfo);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const mergedBeforeUpload = async (file: RcFile, fileListArgs: RcFile[]) => {
|
const mergedBeforeUpload = async (file: RcFile, fileListArgs: RcFile[]) => {
|
||||||
|
@ -7,7 +7,7 @@ import type { RcFile, UploadFile, UploadProps } from '..';
|
|||||||
import Upload from '..';
|
import Upload from '..';
|
||||||
import mountTest from '../../../tests/shared/mountTest';
|
import mountTest from '../../../tests/shared/mountTest';
|
||||||
import rtlTest from '../../../tests/shared/rtlTest';
|
import rtlTest from '../../../tests/shared/rtlTest';
|
||||||
import { fireEvent, render, waitFakeTimer, act } from '../../../tests/utils';
|
import { act, fireEvent, render, waitFakeTimer } from '../../../tests/utils';
|
||||||
import Form from '../../form';
|
import Form from '../../form';
|
||||||
import { resetWarned } from '../../_util/warning';
|
import { resetWarned } from '../../_util/warning';
|
||||||
import { getFileItem, isImageUrl, removeFileItem } from '../utils';
|
import { getFileItem, isImageUrl, removeFileItem } from '../utils';
|
||||||
@ -946,4 +946,51 @@ describe('Upload', () => {
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('prevent auto batch in control mode', async () => {
|
||||||
|
const mockFile1 = new File(['bamboo'], 'bamboo.png', { type: 'image/png' });
|
||||||
|
const mockFile2 = new File(['light'], 'light.png', { type: 'image/png' });
|
||||||
|
|
||||||
|
const customRequest = jest.fn(async (options) => {
|
||||||
|
// stop here to make sure new fileList has been set and passed to Upload
|
||||||
|
// eslint-disable-next-line no-promise-executor-return
|
||||||
|
await new Promise((resolve) => setTimeout(resolve, 0));
|
||||||
|
options.onProgress({ percent: 0 });
|
||||||
|
const url = Promise.resolve<string>('https://ant.design');
|
||||||
|
options.onProgress({ percent: 100 });
|
||||||
|
options.onSuccess({}, { ...options.file, url });
|
||||||
|
});
|
||||||
|
|
||||||
|
let fileListOut: UploadProps['fileList'] = [];
|
||||||
|
|
||||||
|
const Demo: React.FC = () => {
|
||||||
|
const [fileList, setFileList] = React.useState<UploadFile[]>([]);
|
||||||
|
|
||||||
|
const onChange: UploadProps['onChange'] = async (e) => {
|
||||||
|
const newFileList = Array.isArray(e) ? e : e.fileList;
|
||||||
|
setFileList(newFileList);
|
||||||
|
|
||||||
|
fileListOut = newFileList;
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Upload customRequest={customRequest} onChange={onChange} fileList={fileList}>
|
||||||
|
<button type="button">Upload</button>
|
||||||
|
</Upload>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const { container } = render(<Demo />);
|
||||||
|
|
||||||
|
fireEvent.change(container.querySelector<HTMLInputElement>('input')!, {
|
||||||
|
target: { files: [mockFile1, mockFile2] },
|
||||||
|
});
|
||||||
|
|
||||||
|
// React 18 is async now
|
||||||
|
await waitFakeTimer();
|
||||||
|
|
||||||
|
fileListOut.forEach((file) => {
|
||||||
|
expect(file.status).toBe('done');
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user