@@ -9,7 +9,6 @@ import useId from 'rc-util/lib/hooks/useId';
99import useLayoutEffect from 'rc-util/lib/hooks/useLayoutEffect' ;
1010import isMobile from 'rc-util/lib/isMobile' ;
1111import * as React from 'react' ;
12- import { flushSync } from 'react-dom' ;
1312import Popup from './Popup' ;
1413import TriggerWrapper from './TriggerWrapper' ;
1514import type { TriggerContextProps } from './context' ;
@@ -320,15 +319,22 @@ export function generateTrigger(
320319 const openRef = React . useRef ( mergedOpen ) ;
321320 openRef . current = mergedOpen ;
322321
322+ const lastTriggerRef = React . useRef < boolean [ ] > ( [ ] ) ;
323+ lastTriggerRef . current = [ ] ;
324+
323325 const internalTriggerOpen = useEvent ( ( nextOpen : boolean ) => {
326+ setMergedOpen ( nextOpen ) ;
327+
324328 // Enter or Pointer will both trigger open state change
325329 // We only need take one to avoid duplicated change event trigger
326- flushSync ( ( ) => {
327- if ( mergedOpen !== nextOpen ) {
328- setMergedOpen ( nextOpen ) ;
329- onPopupVisibleChange ?.( nextOpen ) ;
330- }
331- } ) ;
330+ // Use `lastTriggerRef` to record last open type
331+ if (
332+ ( lastTriggerRef . current [ lastTriggerRef . current . length - 1 ] ??
333+ mergedOpen ) !== nextOpen
334+ ) {
335+ lastTriggerRef . current . push ( nextOpen ) ;
336+ onPopupVisibleChange ?.( nextOpen ) ;
337+ }
332338 } ) ;
333339
334340 // Trigger for delay
0 commit comments