From 52cb37f487b8e69bcbd46c4d510ed0bcde935f5b Mon Sep 17 00:00:00 2001 From: lijianan <574980606@qq.com> Date: Sat, 19 Nov 2022 13:45:56 +0800 Subject: [PATCH] chore: remove throttleByAnimationFrameDecorator (#38693) * chore: remove throttleByAnimationFrameDecorator * fix * fix --- components/_util/__tests__/util.test.tsx | 21 +--------- components/_util/throttleByAnimationFrame.tsx | 41 ++++--------------- components/affix/index.tsx | 32 ++++----------- components/back-top/index.tsx | 6 +-- components/float-button/BackTop.tsx | 6 +-- 5 files changed, 23 insertions(+), 83 deletions(-) diff --git a/components/_util/__tests__/util.test.tsx b/components/_util/__tests__/util.test.tsx index eacfa6148c..d82d8d93c9 100644 --- a/components/_util/__tests__/util.test.tsx +++ b/components/_util/__tests__/util.test.tsx @@ -6,10 +6,7 @@ import { waitFakeTimer, render, fireEvent } from '../../../tests/utils'; import getDataOrAriaProps from '../getDataOrAriaProps'; import delayRaf from '../raf'; import { isStyleSupport } from '../styleChecker'; -import { - throttleByAnimationFrame, - throttleByAnimationFrameDecorator, -} from '../throttleByAnimationFrame'; +import throttleByAnimationFrame from '../throttleByAnimationFrame'; import TransButton from '../transButton'; describe('Test utils function', () => { @@ -49,22 +46,6 @@ describe('Test utils function', () => { 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', () => { diff --git a/components/_util/throttleByAnimationFrame.tsx b/components/_util/throttleByAnimationFrame.tsx index c04923cd40..4b3c80826a 100644 --- a/components/_util/throttleByAnimationFrame.tsx +++ b/components/_util/throttleByAnimationFrame.tsx @@ -1,6 +1,10 @@ import raf from 'rc-util/lib/raf'; -export function throttleByAnimationFrame(fn: (...args: T) => void) { +type throttledFn = (...args: any[]) => void; + +type throttledCancelFn = { cancel: () => void }; + +function throttleByAnimationFrame(fn: (...args: T) => void) { let requestId: number | null; const later = (args: T) => () => { @@ -8,10 +12,7 @@ export function throttleByAnimationFrame(fn: (...args: T) = fn(...args); }; - const throttled: { - (...args: T): void; - cancel: () => void; - } = (...args: T) => { + const throttled: throttledFn & throttledCancelFn = (...args: T) => { if (requestId == null) { requestId = raf(later(args)); } @@ -25,32 +26,4 @@ export function throttleByAnimationFrame(fn: (...args: T) = return throttled; } -export function throttleByAnimationFrameDecorator() { - 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; - }, - }; - }; -} +export default throttleByAnimationFrame; diff --git a/components/affix/index.tsx b/components/affix/index.tsx index df871dfd84..debf898dc8 100644 --- a/components/affix/index.tsx +++ b/components/affix/index.tsx @@ -4,7 +4,7 @@ import omit from 'rc-util/lib/omit'; import * as React from 'react'; import type { ConfigConsumerProps } from '../config-provider'; import { ConfigContext } from '../config-provider'; -import { throttleByAnimationFrameDecorator } from '../_util/throttleByAnimationFrame'; +import throttleByAnimationFrame from '../_util/throttleByAnimationFrame'; import useStyle from './style'; import { @@ -126,9 +126,9 @@ class Affix extends React.Component { componentWillUnmount() { clearTimeout(this.timeout); removeObserveTarget(this); - (this.updatePosition as any).cancel(); + this.updatePosition.cancel(); // https://github.com/ant-design/ant-design/issues/22683 - (this.lazyUpdatePosition as any).cancel(); + this.lazyUpdatePosition.cancel(); } getOffsetTop = () => { @@ -228,14 +228,11 @@ class Affix extends React.Component { } }; - // Handle realign logic - @throttleByAnimationFrameDecorator() - updatePosition() { + updatePosition = throttleByAnimationFrame(() => { this.prepareMeasure(); - } + }); - @throttleByAnimationFrameDecorator() - lazyUpdatePosition() { + lazyUpdatePosition = throttleByAnimationFrame(() => { const targetFunc = this.getTargetFunc(); const { affixStyle } = this.state; @@ -262,7 +259,7 @@ class Affix extends React.Component { // Directly call prepare measure since it's already throttled. this.prepareMeasure(); - } + }); // =================== Render =================== render() { @@ -288,21 +285,11 @@ class Affix extends React.Component { } return ( - { - this.updatePosition(); - }} - > +
{affixStyle && @@ -321,7 +308,6 @@ const AffixFC = React.forwardRef((props, ref) => { const AffixProps: InternalAffixProps = { ...props, - affixPrefixCls, rootClassName: hashId, }; diff --git a/components/back-top/index.tsx b/components/back-top/index.tsx index b67aca5ad7..a7c68be867 100644 --- a/components/back-top/index.tsx +++ b/components/back-top/index.tsx @@ -9,7 +9,7 @@ import { ConfigContext } from '../config-provider'; import getScroll from '../_util/getScroll'; import { cloneElement } from '../_util/reactNode'; import scrollTo from '../_util/scrollTo'; -import { throttleByAnimationFrame } from '../_util/throttleByAnimationFrame'; +import throttleByAnimationFrame from '../_util/throttleByAnimationFrame'; import warning from '../_util/warning'; import useStyle from './style'; @@ -32,7 +32,7 @@ interface ChildrenProps { visible?: boolean; // Only for test. Don't use it. } -const BackTopContent: React.FC = props => { +const BackTopContent: React.FC = (props) => { const { prefixCls, rootPrefixCls, children, visible } = props; const defaultElement = (
@@ -52,7 +52,7 @@ const BackTopContent: React.FC = props => { ); }; -const BackTop: React.FC = props => { +const BackTop: React.FC = (props) => { const [visible, setVisible] = useMergedState(false, { value: props.visible, }); diff --git a/components/float-button/BackTop.tsx b/components/float-button/BackTop.tsx index 847a0f2ad4..7d2431e22b 100644 --- a/components/float-button/BackTop.tsx +++ b/components/float-button/BackTop.tsx @@ -9,12 +9,12 @@ import type { ConfigConsumerProps } from '../config-provider'; import { ConfigContext } from '../config-provider'; import getScroll from '../_util/getScroll'; import scrollTo from '../_util/scrollTo'; -import { throttleByAnimationFrame } from '../_util/throttleByAnimationFrame'; +import throttleByAnimationFrame from '../_util/throttleByAnimationFrame'; import FloatButtonGroupContext from './context'; import type { BackTopProps, FloatButtonShape } from './interface'; import useStyle from './style'; -const BackTop: React.FC = props => { +const BackTop: React.FC = (props) => { const { prefixCls: customizePrefixCls, className = '', @@ -63,7 +63,7 @@ const BackTop: React.FC = props => { }; }, [target]); - const scrollToTop: React.MouseEventHandler = e => { + const scrollToTop: React.MouseEventHandler = (e) => { scrollTo(0, { getContainer: target || getDefaultTarget, duration }); if (typeof onClick === 'function') { onClick(e);