Browse Source

chore: remove throttleByAnimationFrameDecorator (#38693)

* chore: remove throttleByAnimationFrameDecorator

* fix

* fix
pull/38666/head
lijianan 2 years ago
committed by GitHub
parent
commit
52cb37f487
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 21
      components/_util/__tests__/util.test.tsx
  2. 41
      components/_util/throttleByAnimationFrame.tsx
  3. 32
      components/affix/index.tsx
  4. 6
      components/back-top/index.tsx
  5. 6
      components/float-button/BackTop.tsx

21
components/_util/__tests__/util.test.tsx

@ -6,10 +6,7 @@ import { waitFakeTimer, render, fireEvent } from '../../../tests/utils';
import getDataOrAriaProps from '../getDataOrAriaProps'; import getDataOrAriaProps from '../getDataOrAriaProps';
import delayRaf from '../raf'; import delayRaf from '../raf';
import { isStyleSupport } from '../styleChecker'; import { isStyleSupport } from '../styleChecker';
import { import throttleByAnimationFrame from '../throttleByAnimationFrame';
throttleByAnimationFrame,
throttleByAnimationFrameDecorator,
} from '../throttleByAnimationFrame';
import TransButton from '../transButton'; import TransButton from '../transButton';
describe('Test utils function', () => { describe('Test utils function', () => {
@ -49,22 +46,6 @@ describe('Test utils function', () => {
expect(callback).not.toHaveBeenCalled(); expect(callback).not.toHaveBeenCalled();
}); });
it('throttleByAnimationFrameDecorator should works', async () => {
const callbackFn = jest.fn();
class Test {
@throttleByAnimationFrameDecorator()
callback() {
callbackFn();
}
}
const test = new Test();
test.callback();
test.callback();
test.callback();
await waitFakeTimer();
expect(callbackFn).toHaveBeenCalledTimes(1);
});
}); });
describe('getDataOrAriaProps', () => { describe('getDataOrAriaProps', () => {

41
components/_util/throttleByAnimationFrame.tsx

@ -1,6 +1,10 @@
import raf from 'rc-util/lib/raf'; import raf from 'rc-util/lib/raf';
export function throttleByAnimationFrame<T extends unknown[]>(fn: (...args: T) => void) { type throttledFn = (...args: any[]) => void;
type throttledCancelFn = { cancel: () => void };
function throttleByAnimationFrame<T extends any[]>(fn: (...args: T) => void) {
let requestId: number | null; let requestId: number | null;
const later = (args: T) => () => { const later = (args: T) => () => {
@ -8,10 +12,7 @@ export function throttleByAnimationFrame<T extends unknown[]>(fn: (...args: T) =
fn(...args); fn(...args);
}; };
const throttled: { const throttled: throttledFn & throttledCancelFn = (...args: T) => {
(...args: T): void;
cancel: () => void;
} = (...args: T) => {
if (requestId == null) { if (requestId == null) {
requestId = raf(later(args)); requestId = raf(later(args));
} }
@ -25,32 +26,4 @@ export function throttleByAnimationFrame<T extends unknown[]>(fn: (...args: T) =
return throttled; return throttled;
} }
export function throttleByAnimationFrameDecorator() { export default throttleByAnimationFrame;
return function throttle(target: any, key: string, descriptor: any) {
const fn = descriptor.value;
let definingProperty = false;
return {
configurable: true,
get() {
// In IE11 calling Object.defineProperty has a side-effect of evaluating the
// getter for the property which is being replaced. This causes infinite
// recursion and an "Out of stack space" error.
// eslint-disable-next-line no-prototype-builtins
if (definingProperty || this === target.prototype || this.hasOwnProperty(key)) {
/* istanbul ignore next */
return fn;
}
const boundFn = throttleByAnimationFrame(fn.bind(this));
definingProperty = true;
Object.defineProperty(this, key, {
value: boundFn,
configurable: true,
writable: true,
});
definingProperty = false;
return boundFn;
},
};
};
}

32
components/affix/index.tsx

@ -4,7 +4,7 @@ import omit from 'rc-util/lib/omit';
import * as React from 'react'; import * as React from 'react';
import type { ConfigConsumerProps } from '../config-provider'; import type { ConfigConsumerProps } from '../config-provider';
import { ConfigContext } from '../config-provider'; import { ConfigContext } from '../config-provider';
import { throttleByAnimationFrameDecorator } from '../_util/throttleByAnimationFrame'; import throttleByAnimationFrame from '../_util/throttleByAnimationFrame';
import useStyle from './style'; import useStyle from './style';
import { import {
@ -126,9 +126,9 @@ class Affix extends React.Component<InternalAffixProps, AffixState> {
componentWillUnmount() { componentWillUnmount() {
clearTimeout(this.timeout); clearTimeout(this.timeout);
removeObserveTarget(this); removeObserveTarget(this);
(this.updatePosition as any).cancel(); this.updatePosition.cancel();
// https://github.com/ant-design/ant-design/issues/22683 // https://github.com/ant-design/ant-design/issues/22683
(this.lazyUpdatePosition as any).cancel(); this.lazyUpdatePosition.cancel();
} }
getOffsetTop = () => { getOffsetTop = () => {
@ -228,14 +228,11 @@ class Affix extends React.Component<InternalAffixProps, AffixState> {
} }
}; };
// Handle realign logic updatePosition = throttleByAnimationFrame(() => {
@throttleByAnimationFrameDecorator()
updatePosition() {
this.prepareMeasure(); this.prepareMeasure();
} });
@throttleByAnimationFrameDecorator() lazyUpdatePosition = throttleByAnimationFrame(() => {
lazyUpdatePosition() {
const targetFunc = this.getTargetFunc(); const targetFunc = this.getTargetFunc();
const { affixStyle } = this.state; const { affixStyle } = this.state;
@ -262,7 +259,7 @@ class Affix extends React.Component<InternalAffixProps, AffixState> {
// Directly call prepare measure since it's already throttled. // Directly call prepare measure since it's already throttled.
this.prepareMeasure(); this.prepareMeasure();
} });
// =================== Render =================== // =================== Render ===================
render() { render() {
@ -288,21 +285,11 @@ class Affix extends React.Component<InternalAffixProps, AffixState> {
} }
return ( return (
<ResizeObserver <ResizeObserver onResize={this.updatePosition}>
onResize={() => {
this.updatePosition();
}}
>
<div {...props} ref={this.savePlaceholderNode}> <div {...props} ref={this.savePlaceholderNode}>
{affixStyle && <div style={placeholderStyle} aria-hidden="true" />} {affixStyle && <div style={placeholderStyle} aria-hidden="true" />}
<div className={className} ref={this.saveFixedNode} style={affixStyle}> <div className={className} ref={this.saveFixedNode} style={affixStyle}>
<ResizeObserver <ResizeObserver onResize={this.updatePosition}>{children}</ResizeObserver>
onResize={() => {
this.updatePosition();
}}
>
{children}
</ResizeObserver>
</div> </div>
</div> </div>
</ResizeObserver> </ResizeObserver>
@ -321,7 +308,6 @@ const AffixFC = React.forwardRef<Affix, AffixProps>((props, ref) => {
const AffixProps: InternalAffixProps = { const AffixProps: InternalAffixProps = {
...props, ...props,
affixPrefixCls, affixPrefixCls,
rootClassName: hashId, rootClassName: hashId,
}; };

6
components/back-top/index.tsx

@ -9,7 +9,7 @@ import { ConfigContext } from '../config-provider';
import getScroll from '../_util/getScroll'; import getScroll from '../_util/getScroll';
import { cloneElement } from '../_util/reactNode'; import { cloneElement } from '../_util/reactNode';
import scrollTo from '../_util/scrollTo'; import scrollTo from '../_util/scrollTo';
import { throttleByAnimationFrame } from '../_util/throttleByAnimationFrame'; import throttleByAnimationFrame from '../_util/throttleByAnimationFrame';
import warning from '../_util/warning'; import warning from '../_util/warning';
import useStyle from './style'; import useStyle from './style';
@ -32,7 +32,7 @@ interface ChildrenProps {
visible?: boolean; // Only for test. Don't use it. visible?: boolean; // Only for test. Don't use it.
} }
const BackTopContent: React.FC<ChildrenProps> = props => { const BackTopContent: React.FC<ChildrenProps> = (props) => {
const { prefixCls, rootPrefixCls, children, visible } = props; const { prefixCls, rootPrefixCls, children, visible } = props;
const defaultElement = ( const defaultElement = (
<div className={`${prefixCls}-content`}> <div className={`${prefixCls}-content`}>
@ -52,7 +52,7 @@ const BackTopContent: React.FC<ChildrenProps> = props => {
); );
}; };
const BackTop: React.FC<BackTopProps> = props => { const BackTop: React.FC<BackTopProps> = (props) => {
const [visible, setVisible] = useMergedState(false, { const [visible, setVisible] = useMergedState(false, {
value: props.visible, value: props.visible,
}); });

6
components/float-button/BackTop.tsx

@ -9,12 +9,12 @@ import type { ConfigConsumerProps } from '../config-provider';
import { ConfigContext } from '../config-provider'; import { ConfigContext } from '../config-provider';
import getScroll from '../_util/getScroll'; import getScroll from '../_util/getScroll';
import scrollTo from '../_util/scrollTo'; import scrollTo from '../_util/scrollTo';
import { throttleByAnimationFrame } from '../_util/throttleByAnimationFrame'; import throttleByAnimationFrame from '../_util/throttleByAnimationFrame';
import FloatButtonGroupContext from './context'; import FloatButtonGroupContext from './context';
import type { BackTopProps, FloatButtonShape } from './interface'; import type { BackTopProps, FloatButtonShape } from './interface';
import useStyle from './style'; import useStyle from './style';
const BackTop: React.FC<BackTopProps> = props => { const BackTop: React.FC<BackTopProps> = (props) => {
const { const {
prefixCls: customizePrefixCls, prefixCls: customizePrefixCls,
className = '', className = '',
@ -63,7 +63,7 @@ const BackTop: React.FC<BackTopProps> = props => {
}; };
}, [target]); }, [target]);
const scrollToTop: React.MouseEventHandler<HTMLDivElement> = e => { const scrollToTop: React.MouseEventHandler<HTMLDivElement> = (e) => {
scrollTo(0, { getContainer: target || getDefaultTarget, duration }); scrollTo(0, { getContainer: target || getDefaultTarget, duration });
if (typeof onClick === 'function') { if (typeof onClick === 'function') {
onClick(e); onClick(e);

Loading…
Cancel
Save