fix: btn loading (#24678)

This commit is contained in:
二货机器人 2020-06-02 12:54:22 +08:00 committed by GitHub
parent b1caef0723
commit d5fea40ab5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 62 additions and 37 deletions

View File

@ -1,5 +1,6 @@
import React, { Component } from 'react';
import { mount, render } from 'enzyme';
import { act } from 'react-dom/test-utils';
import { SearchOutlined } from '@ant-design/icons';
import Button from '..';
import ConfigProvider from '../../config-provider';
@ -165,6 +166,22 @@ describe('Button', () => {
expect(wrapper.hasClass('ant-btn-loading')).toBe(false);
});
it('reset when loading back of delay', () => {
jest.useFakeTimers();
const wrapper = mount(<Button loading={{ delay: 1000 }} />);
wrapper.update();
wrapper.setProps({ loading: false });
act(() => {
jest.runAllTimers();
wrapper.update();
});
expect(wrapper.find('.ant-btn-loading')).toHaveLength(0);
jest.useRealTimers();
});
it('should not clickable when button is loading', () => {
const onClick = jest.fn();
const wrapper = mount(

View File

@ -122,15 +122,29 @@ interface CompoundedComponent
}
const InternalButton: React.ForwardRefRenderFunction<unknown, ButtonProps> = (props, ref) => {
const {
loading,
prefixCls: customizePrefixCls,
type,
danger,
shape,
size: customizeSize,
className,
children,
icon,
ghost,
block,
...rest
} = props;
const size = React.useContext(SizeContext);
const [loading, setLoading] = React.useState(props.loading);
const [innerLoading, setLoading] = React.useState(loading);
const [hasTwoCNChar, setHasTwoCNChar] = React.useState(false);
const { getPrefixCls, autoInsertSpaceInButton, direction } = React.useContext(ConfigContext);
const buttonRef = (ref as any) || React.createRef<HTMLElement>();
let delayTimeout: number;
const delayTimeoutRef = React.useRef<number>();
const isNeedInserted = () => {
const { icon, children, type } = props;
return React.Children.count(children) === 1 && !icon && type !== 'link' && type !== 'text';
};
@ -150,17 +164,15 @@ const InternalButton: React.ForwardRefRenderFunction<unknown, ButtonProps> = (pr
};
React.useEffect(() => {
if (props.loading && typeof props.loading !== 'boolean') {
clearTimeout(delayTimeout);
if (typeof loading === 'object' && loading.delay) {
delayTimeoutRef.current = window.setTimeout(() => {
setLoading(loading);
}, loading.delay);
} else {
clearTimeout(delayTimeoutRef.current);
setLoading(loading);
}
if (props.loading && typeof props.loading !== 'boolean' && props.loading.delay) {
delayTimeout = window.setTimeout(() => {
setLoading(props.loading);
}, props.loading.delay);
} else if (props.loading !== loading) {
setLoading(props.loading);
}
}, [props.loading]);
}, [loading]);
React.useEffect(() => {
fixTwoCNChar();
@ -168,26 +180,13 @@ const InternalButton: React.ForwardRefRenderFunction<unknown, ButtonProps> = (pr
const handleClick = (e: React.MouseEvent<HTMLButtonElement | HTMLAnchorElement, MouseEvent>) => {
const { onClick } = props;
if (loading) {
if (innerLoading) {
return;
}
if (onClick) {
(onClick as React.MouseEventHandler<HTMLButtonElement | HTMLAnchorElement>)(e);
}
};
const {
prefixCls: customizePrefixCls,
type,
danger,
shape,
size: customizeSize,
className,
children,
icon,
ghost,
block,
...rest
} = props;
devWarning(
!(typeof icon === 'string' && icon.length > 2),
@ -212,7 +211,7 @@ const InternalButton: React.ForwardRefRenderFunction<unknown, ButtonProps> = (pr
break;
}
const iconType = loading ? 'loading' : icon;
const iconType = innerLoading ? 'loading' : icon;
const classes = classNames(prefixCls, className, {
[`${prefixCls}-${type}`]: type,
@ -220,7 +219,7 @@ const InternalButton: React.ForwardRefRenderFunction<unknown, ButtonProps> = (pr
[`${prefixCls}-${sizeCls}`]: sizeCls,
[`${prefixCls}-icon-only`]: !children && children !== 0 && iconType,
[`${prefixCls}-background-ghost`]: ghost,
[`${prefixCls}-loading`]: loading,
[`${prefixCls}-loading`]: innerLoading,
[`${prefixCls}-two-chinese-chars`]: hasTwoCNChar && autoInsertSpace,
[`${prefixCls}-block`]: block,
[`${prefixCls}-dangerous`]: !!danger,
@ -228,10 +227,10 @@ const InternalButton: React.ForwardRefRenderFunction<unknown, ButtonProps> = (pr
});
const iconNode =
icon && !loading ? (
icon && !innerLoading ? (
icon
) : (
<LoadingIcon existIcon={!!icon} prefixCls={prefixCls} loading={loading} />
<LoadingIcon existIcon={!!icon} prefixCls={prefixCls} loading={innerLoading} />
);
const kids =

View File

@ -23,14 +23,23 @@ class App extends React.Component {
};
enterLoading = index => {
const newLoadings = [...this.state.loadings];
newLoadings[index] = true;
this.setState({
loadings: newLoadings,
this.setState(({ loadings }) => {
const newLoadings = [...loadings];
newLoadings[index] = true;
return {
loadings: newLoadings,
};
});
setTimeout(() => {
newLoadings[index] = false;
this.setState({ loadings: newLoadings });
this.setState(({ loadings }) => {
const newLoadings = [...loadings];
newLoadings[index] = false;
return {
loadings: newLoadings,
};
});
}, 6000);
};