Skip to content

Commit 670ff3f

Browse files
siaikinsiaikin
andauthored
fix: useMergedState is not updated in time (#6402)
Co-authored-by: siaikin <[email protected]>
1 parent a8294a9 commit 670ff3f

File tree

4 files changed

+71
-12
lines changed

4 files changed

+71
-12
lines changed

components/_util/hooks/useMergedState.ts

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { Ref, UnwrapRef } from 'vue';
2-
import { toRaw, watchEffect, unref, watch, ref } from 'vue';
2+
import { computed, ref, toRaw, unref, watch } from 'vue';
33

44
export default function useMergedState<T, R = Ref<T>>(
55
defaultStateValue: T | (() => T),
@@ -21,19 +21,26 @@ export default function useMergedState<T, R = Ref<T>>(
2121
}
2222

2323
const innerValue = ref(initValue) as Ref<T>;
24-
const mergedValue = ref(initValue) as Ref<T>;
25-
watchEffect(() => {
26-
let val = value.value !== undefined ? value.value : innerValue.value;
27-
if (option.postState) {
28-
val = option.postState(val as T);
29-
}
30-
mergedValue.value = val as T;
24+
const innerMergedValue = ref(initValue) as Ref<T>;
25+
const exposeValue = computed({
26+
get: () => {
27+
let val = innerValue.value;
28+
if (option.postState) {
29+
val = option.postState(val as T);
30+
}
31+
innerMergedValue.value = val as T;
32+
33+
return innerMergedValue.value;
34+
},
35+
set: (val: T) => {
36+
triggerChange(val);
37+
},
3138
});
3239

3340
function triggerChange(newValue: T) {
34-
const preVal = mergedValue.value;
41+
const preVal = innerMergedValue.value;
3542
innerValue.value = newValue;
36-
if (toRaw(mergedValue.value) !== newValue && option.onChange) {
43+
if (toRaw(innerMergedValue.value) !== newValue && option.onChange) {
3744
option.onChange(newValue, preVal);
3845
}
3946
}
@@ -43,5 +50,5 @@ export default function useMergedState<T, R = Ref<T>>(
4350
innerValue.value = value.value as T;
4451
});
4552

46-
return [mergedValue as unknown as R, triggerChange];
53+
return [exposeValue as unknown as R, triggerChange];
4754
}

components/upload/__tests__/__snapshots__/uploadlist.test.js.snap

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,22 @@ exports[`Upload List handle error 2`] = `
3232
</div></span></div></span></span>
3333
`;
3434

35+
exports[`Upload List handle sync throw error 1`] = `
36+
<span><div class="ant-upload ant-upload-select ant-upload-select-text"><span role="button" tabindex="0" class="ant-upload"><input type="file" accept="" style="display: none;"><button>upload</button></span></div><span tag="div" class="ant-upload-list ant-upload-list-text"><div class=""><span><div class="ant-upload-list-item ant-upload-list-item-uploading ant-upload-list-item-list-type-text"><div class="ant-upload-list-item-info"><span><span role="img" aria-label="loading" class="anticon anticon-loading"><svg viewBox="0 0 1024 1024" focusable="false" data-icon="loading" width="1em" height="1em" fill="currentColor" aria-hidden="true" class="anticon-spin"><path d="M988 548c-19.9 0-36-16.1-36-36 0-59.4-11.6-117-34.6-171.3a440.45 440.45 0 00-94.3-139.9 437.71 437.71 0 00-139.9-94.3C629 83.6 571.4 72 512 72c-19.9 0-36-16.1-36-36s16.1-36 36-36c69.1 0 136.2 13.5 199.3 40.3C772.3 66 827 103 874 150c47 47 83.9 101.8 109.7 162.7 26.7 63.1 40.2 130.2 40.2 199.3.1 19.9-16 36-35.9 36z"></path></svg></span><span title="foo.png" class="ant-upload-list-item-name">foo.png</span><span class="ant-upload-list-item-card-actions "><a title="Remove file"><span role="img" aria-label="delete" tabindex="-1" title="Remove file" class="anticon anticon-delete"><svg viewBox="64 64 896 896" focusable="false" data-icon="delete" width="1em" height="1em" fill="currentColor" aria-hidden="true" class=""><path d="M360 184h-8c4.4 0 8-3.6 8-8v8h304v-8c0 4.4 3.6 8 8 8h-8v72h72v-80c0-35.3-28.7-64-64-64H352c-35.3 0-64 28.7-64 64v80h72v-72zm504 72H160c-17.7 0-32 14.3-32 32v32c0 4.4 3.6 8 8 8h60.4l24.7 523c1.6 34.1 29.8 61 63.9 61h454c34.2 0 62.3-26.8 63.9-61l24.7-523H888c4.4 0 8-3.6 8-8v-32c0-17.7-14.3-32-32-32zM731.3 840H292.7l-24.2-512h487l-24.2 512z"></path></svg></span></a></span></span></div>
37+
<div class="ant-upload-list-item-progress">
38+
<div class="ant-progress ant-progress-line ant-progress-status-normal ant-progress-default">
39+
<div>
40+
<div class="ant-progress-outer">
41+
<div class="ant-progress-inner">
42+
<div class="ant-progress-bg" style="width: 0%; height: 2px; border-radius: 100px;"></div>
43+
</div>
44+
</div>
45+
</div>
46+
</div>
47+
</div>
48+
</div></span></div></span></span>
49+
`;
50+
3551
exports[`Upload List should be uploading when upload a file 1`] = `<span><div class="ant-upload ant-upload-select ant-upload-select-text"><span role="button" tabindex="0" class="ant-upload"><input type="file" accept="" style="display: none;"><button>upload</button></span></div><span tag="div" class="ant-upload-list ant-upload-list-text"></span></span>`;
3652
3753
exports[`Upload List should non-image format file preview 1`] = `

components/upload/__tests__/requests.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,7 @@ export const errorRequest = ({ onError }) => {
99
onError();
1010
});
1111
};
12+
13+
export const syncErrorRequest = ({ onError }) => {
14+
onError();
15+
};

components/upload/__tests__/uploadlist.test.js

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { mount } from '@vue/test-utils';
22
import * as Vue from 'vue';
33
import Upload from '..';
4-
import { errorRequest, successRequest } from './requests';
4+
import { errorRequest, successRequest, syncErrorRequest } from './requests';
55
import PropsTypes from '../../_util/vue-types';
66
import { uploadListProps } from '../interface';
77
import { sleep } from '../../../tests/utils';
@@ -165,6 +165,38 @@ describe('Upload List', () => {
165165
}, 0);
166166
});
167167

168+
xit('handle sync throw error', done => {
169+
const props = {
170+
props: {
171+
action: 'https://www.mocky.io/v2/5cc8019d300000980a055e76',
172+
customRequest: syncErrorRequest,
173+
},
174+
listeners: {
175+
change: ({ file }) => {
176+
if (file.status !== 'uploading') {
177+
expect(wrapper.html()).toMatchSnapshot();
178+
done();
179+
}
180+
},
181+
},
182+
slots: {
183+
default: () => h('button', 'upload'),
184+
},
185+
sync: false,
186+
};
187+
const wrapper = mount(Upload, props);
188+
setTimeout(() => {
189+
const mockFile = new File(['foo'], 'foo.png', {
190+
type: 'image/png',
191+
});
192+
wrapper.findComponent({ name: 'ajaxUploader' }).vm.onChange({
193+
target: {
194+
files: [mockFile],
195+
},
196+
});
197+
}, 0);
198+
});
199+
168200
xit('does concat filelist when beforeUpload returns false', done => {
169201
const handleChange = jest.fn();
170202
const props = {

0 commit comments

Comments
 (0)