diff --git a/components/affix/index.tsx b/components/affix/index.tsx index 5eacc0e654..3122a7abc0 100644 --- a/components/affix/index.tsx +++ b/components/affix/index.tsx @@ -52,7 +52,11 @@ export interface AffixState { prevTarget: Window | HTMLElement | null; } -const Affix: React.FC = (props) => { +interface AffixRef { + updatePosition: ReturnType; +} + +const Affix = React.forwardRef((props, ref) => { const { rootClassName: customizeRootClassName, children, @@ -134,9 +138,8 @@ const Affix: React.FC = (props) => { }); }; - const lazyUpdatePosition = throttleByAnimationFrame(() => { + const updatePosition = throttleByAnimationFrame(() => { // Check position change before measure to make Safari smooth - if (target && placeholderNodeRef.current) { const targetRect = getTargetRect(target); const placeholderRect = getTargetRect(placeholderNodeRef.current); @@ -152,10 +155,12 @@ const Affix: React.FC = (props) => { measure(); }); + React.useImperativeHandle(ref, () => ({ updatePosition })); + useEffect(() => { timerRef.current = setTimeout(() => { TRIGGER_EVENTS.forEach((eventName) => { - target?.addEventListener(eventName, lazyUpdatePosition); + target?.addEventListener(eventName, updatePosition); }); measure(); }); @@ -165,10 +170,10 @@ const Affix: React.FC = (props) => { timerRef.current = null; } TRIGGER_EVENTS.forEach((eventName) => { - target?.removeEventListener(eventName, lazyUpdatePosition); + target?.removeEventListener(eventName, updatePosition); }); - lazyUpdatePosition.cancel(); + updatePosition.cancel(); }; }, [offsetTop, offsetBottom, customizeTarget, getTargetContainer]); const [wrapSSR, hashId] = useStyle(affixPrefixCls); @@ -188,16 +193,16 @@ const Affix: React.FC = (props) => { ]); return wrapSSR( - +
{affixStyle && , ); -}; +}); if (process.env.NODE_ENV !== 'production') { Affix.displayName = 'Affix';