diff --git a/components/avatar/__tests__/Avatar.test.js b/components/avatar/__tests__/Avatar.test.js index 52e2d2ed64..877f3edb7c 100644 --- a/components/avatar/__tests__/Avatar.test.js +++ b/components/avatar/__tests__/Avatar.test.js @@ -15,7 +15,8 @@ describe('Avatar Render', () => { const wrapper = mount(Fallback, { attachTo: div }); wrapper.instance().setScale = jest.fn(() => wrapper.instance().setState({ scale: 0.5 })); - wrapper.setState({ isImgExist: false }); + + wrapper.find('img').simulate('error'); const children = wrapper.find('.ant-avatar-string'); expect(children.length).toBe(1); @@ -26,4 +27,41 @@ describe('Avatar Render', () => { wrapper.detach(); global.document.body.removeChild(div); }); + + it('should handle onError correctly', () => { + const LOAD_FAILURE_SRC = 'http://error.url'; + const LOAD_SUCCESS_SRC = 'https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png'; + + const div = global.document.createElement('div'); + global.document.body.appendChild(div); + + class Foo extends React.Component { + state = { + src: LOAD_FAILURE_SRC, + } + + handleImgError = () => { + this.setState({ + src: LOAD_SUCCESS_SRC, + }); + return false; + } + + render() { + const { src } = this.state; + return ; + } + } + + const wrapper = mount(, { attachTo: div }); + // mock img load Error, since jsdom do not load resource by default + // https://github.com/jsdom/jsdom/issues/1816 + wrapper.find('img').simulate('error'); + + expect(wrapper.find(Avatar).instance().state.isImgExist).toBe(true); + expect(div.querySelector('img').getAttribute('src')).toBe(LOAD_SUCCESS_SRC); + + wrapper.detach(); + global.document.body.removeChild(div); + }); }); diff --git a/components/avatar/index.en-US.md b/components/avatar/index.en-US.md index 9b4f7efe3f..4e231e4c8b 100644 --- a/components/avatar/index.en-US.md +++ b/components/avatar/index.en-US.md @@ -14,4 +14,5 @@ Avatars can be used to represent people or objects. It supports images, `Icon`s, | shape | the shape of avatar | `circle` \| `square` | `circle` | | size | the size of the avatar | `large` \| `small` \| `default` | `default` | | src | the address of the image for an image avatar | string | - | -| alt | This attribute defines the alternative text describing the image | string | - | \ No newline at end of file +| alt | This attribute defines the alternative text describing the image | string | - | +| onError | handler when img load error,return false to prevent default fallback behavior | () => boolean | - | diff --git a/components/avatar/index.tsx b/components/avatar/index.tsx index 7b83bd9d3f..3da00b8bf2 100644 --- a/components/avatar/index.tsx +++ b/components/avatar/index.tsx @@ -17,6 +17,9 @@ export interface AvatarProps { className?: string; children?: any; alt?: string; + /* callback when img load error */ + /* return false to prevent Avatar show default fallback behavior, then you can do fallback by your self*/ + onError?: () => boolean; } export interface AvatarState { @@ -72,7 +75,13 @@ export default class Avatar extends React.Component { } } - handleImgLoadError = () => this.setState({ isImgExist: false }); + handleImgLoadError = () => { + const { onError } = this.props; + const errorFlag = onError ? onError() : undefined; + if (errorFlag !== false) { + this.setState({ isImgExist: false }); + } + } render() { const { diff --git a/components/avatar/index.zh-CN.md b/components/avatar/index.zh-CN.md index e6b4cc3ae8..3aa304b628 100644 --- a/components/avatar/index.zh-CN.md +++ b/components/avatar/index.zh-CN.md @@ -16,3 +16,4 @@ title: Avatar | size | 设置头像的大小 | Enum{ 'large', 'small', 'default' } | `default` | | src | 图片类头像的资源地址 | string | - | | alt | 图像无法显示时的替代文本 | string | - | +| onError | 图片加载失败的事件,返回 false 会关闭组件默认的 fallback 行为 | () => boolean | - |