Skip to content

Commit 9d1e7a4

Browse files
linxianxizombieJ
andauthored
fix: should not trigger isImageValid.then when src changed (#281)
* fix: should not trigger isImageValid.then when src changed * chore: remove code * test: update test --------- Co-authored-by: 二货机器人 <smith3816@gmail.com>
1 parent ee9ec43 commit 9d1e7a4

File tree

2 files changed

+33
-13
lines changed

2 files changed

+33
-13
lines changed

src/hooks/useStatus.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,21 @@ export default function useStatus({
1414
}) {
1515
const [status, setStatus] = useState<ImageStatus>(isCustomPlaceholder ? 'loading' : 'normal');
1616
const isLoaded = useRef(false);
17-
1817
const isError = status === 'error';
1918

2019
// https://github.com/react-component/image/pull/187
2120
useEffect(() => {
21+
let isCurrentSrc = true;
2222
isImageValid(src).then(isValid => {
23-
if (!isValid) {
23+
// https://github.com/ant-design/ant-design/issues/44948
24+
// If src changes, the previous setStatus should not be triggered
25+
if (!isValid && isCurrentSrc) {
2426
setStatus('error');
2527
}
2628
});
29+
return () => {
30+
isCurrentSrc = false;
31+
};
2732
}, [src]);
2833

2934
useEffect(() => {
@@ -40,10 +45,7 @@ export default function useStatus({
4045

4146
const getImgRef = (img?: HTMLImageElement) => {
4247
isLoaded.current = false;
43-
if (status !== 'loading') {
44-
return;
45-
}
46-
if (img?.complete && (img.naturalWidth || img.naturalHeight)) {
48+
if (status === 'loading' && img?.complete && (img.naturalWidth || img.naturalHeight)) {
4749
isLoaded.current = true;
4850
onLoad();
4951
}

tests/fallback.test.tsx

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,27 @@ import { act, fireEvent, render } from '@testing-library/react';
22
import React from 'react';
33
import Image from '../src';
44

5+
global.lastResolve = null;
6+
57
jest.mock('../src/util', () => {
68
const { isImageValid, ...rest } = jest.requireActual('../src/util');
79

810
return {
911
...rest,
10-
isImageValid: () => Promise.resolve(false),
12+
isImageValid: () =>
13+
new Promise(resolve => {
14+
global.lastResolve = resolve;
15+
16+
setTimeout(() => {
17+
resolve(false);
18+
}, 1000);
19+
}),
1120
};
1221
});
1322

1423
describe('Fallback', () => {
1524
beforeEach(() => {
25+
global.lastResolve = null;
1626
jest.useFakeTimers();
1727
});
1828

@@ -50,18 +60,19 @@ describe('Fallback', () => {
5060
expect(document.querySelector('.rc-image-preview-img')).toHaveAttribute('src', fallback);
5161
});
5262

53-
it('should not show preview', () => {
63+
it('should not show preview', async () => {
5464
const { container } = render(<Image src="abc" fallback={fallback} />);
5565

5666
fireEvent.error(container.querySelector('.rc-image-img'));
57-
act(() => {
67+
await act(async () => {
5868
jest.runAllTimers();
69+
await Promise.resolve();
5970
});
6071

6172
expect(container.querySelector('.rc-image-mask')).toBeFalsy();
6273
});
6374

64-
it('should change image, not error', () => {
75+
it('should change image, not error', async () => {
6576
const { container, rerender } = render(
6677
<Image
6778
width={200}
@@ -70,18 +81,25 @@ describe('Fallback', () => {
7081
/>,
7182
);
7283

73-
fireEvent.error(container.querySelector('.rc-image-img'));
74-
7584
rerender(
7685
<Image
7786
width={200}
7887
src="https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*NZuwQp_vcIQAAAAAAAAAAABkARQnAQ"
7988
fallback="https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png"
8089
/>,
8190
);
82-
act(() => {
91+
92+
// New Image should pass
93+
await act(async () => {
94+
await global.lastResolve(true);
95+
});
96+
97+
// Origin one should failed
98+
await act(async () => {
8399
jest.runAllTimers();
100+
await Promise.resolve();
84101
});
102+
85103
expect(container.querySelector('.rc-image-img')).toHaveAttribute(
86104
'src',
87105
'https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*NZuwQp_vcIQAAAAAAAAAAABkARQnAQ',

0 commit comments

Comments
 (0)