Skip to content

Commit 499862b

Browse files
authored
fix: when popupVisible back to undefined, it should be false (#335)
1 parent 458a553 commit 499862b

File tree

2 files changed

+59
-16
lines changed

2 files changed

+59
-16
lines changed

src/index.tsx

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import ResizeObserver from 'rc-resize-observer';
55
import useEvent from 'rc-util/lib/hooks/useEvent';
66
import useId from 'rc-util/lib/hooks/useId';
77
import useLayoutEffect from 'rc-util/lib/hooks/useLayoutEffect';
8-
import useMergedState from 'rc-util/lib/hooks/useMergedState';
98
import * as React from 'react';
109
import type { TriggerContextProps } from './context';
1110
import TriggerContext from './context';
@@ -266,12 +265,24 @@ export function generateTrigger(
266265
);
267266

268267
// ============================ Open ============================
269-
const [mergedOpen, setMergedOpen] = useMergedState(
268+
const [internalOpen, setInternalOpen] = React.useState(
270269
defaultPopupVisible || false,
271-
{
272-
value: popupVisible,
273-
},
274270
);
271+
272+
// Render still use props as first priority
273+
const mergedOpen = popupVisible ?? internalOpen;
274+
275+
// We use effect sync here in case `popupVisible` back to `undefined`
276+
const setMergedOpen = useEvent((nextOpen: boolean) => {
277+
if (popupVisible === undefined) {
278+
setInternalOpen(nextOpen);
279+
}
280+
});
281+
282+
useLayoutEffect(() => {
283+
setInternalOpen(popupVisible || false);
284+
}, [popupVisible]);
285+
275286
const openRef = React.useRef(mergedOpen);
276287
openRef.current = mergedOpen;
277288

tests/basic.test.jsx

Lines changed: 43 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,11 @@
11
/* eslint-disable max-classes-per-file */
22

3-
import {
4-
act,
5-
cleanup,
6-
fireEvent,
7-
render,
8-
} from '@testing-library/react';
3+
import { act, cleanup, fireEvent, render } from '@testing-library/react';
94
import { spyElementPrototypes } from 'rc-util/lib/test/domHook';
105
import React, { createRef, StrictMode } from 'react';
116
import ReactDOM from 'react-dom';
127
import Trigger from '../src';
13-
import { placementAlignMap, awaitFakeTimer } from './util';
8+
import { awaitFakeTimer, placementAlignMap } from './util';
149

1510
describe('Trigger.Basic', () => {
1611
beforeEach(() => {
@@ -866,14 +861,23 @@ describe('Trigger.Basic', () => {
866861
<div
867862
id="btn"
868863
onClick={() => {
869-
setPlacementAlign(prev => prev === placementAlignMap.left ? placementAlignMap.leftTop: placementAlignMap.left);
864+
setPlacementAlign((prev) =>
865+
prev === placementAlignMap.left
866+
? placementAlignMap.leftTop
867+
: placementAlignMap.left,
868+
);
870869
}}
871870
>
872871
click
873872
</div>
874-
<div id="close" onClick={() => {
875-
setOpen(false);
876-
}}>close</div>
873+
<div
874+
id="close"
875+
onClick={() => {
876+
setOpen(false);
877+
}}
878+
>
879+
close
880+
</div>
877881
</div>
878882
</Trigger>
879883
</>
@@ -891,4 +895,32 @@ describe('Trigger.Basic', () => {
891895
await awaitFakeTimer();
892896
expect(onPopupAlign).toHaveBeenCalledTimes(2);
893897
});
898+
899+
it.only('popupVisible switch `undefined` and `false` should work', async () => {
900+
const Demo = (props) => (
901+
<Trigger
902+
action={['click']}
903+
popupAlign={placementAlignMap.topRight}
904+
popup={<strong>trigger</strong>}
905+
{...props}
906+
>
907+
<div className="target">click</div>
908+
</Trigger>
909+
);
910+
911+
const { container, rerender } = render(<Demo />);
912+
913+
trigger(container, '.target');
914+
expect(document.querySelector('.rc-trigger-popup')).toBeTruthy();
915+
916+
// Back to false
917+
rerender(<Demo popupVisible={false} />);
918+
await awaitFakeTimer();
919+
expect(document.querySelector('.rc-trigger-popup-hidden')).toBeTruthy();
920+
921+
// Back to undefined
922+
rerender(<Demo popupVisible={undefined} />);
923+
await awaitFakeTimer();
924+
expect(document.querySelector('.rc-trigger-popup-hidden')).toBeTruthy();
925+
});
894926
});

0 commit comments

Comments
 (0)