diff --git a/src/DialogWrap.tsx b/src/DialogWrap.tsx index 76563968..cac6b48e 100644 --- a/src/DialogWrap.tsx +++ b/src/DialogWrap.tsx @@ -28,6 +28,7 @@ const DialogWrap: React.FC = (props) => { } = props; const { scrollLock: _, ...restProps } = props; const [animatedVisible, setAnimatedVisible] = React.useState(visible); + const hasOpenedRef = React.useRef(visible); const refContext = React.useMemo(() => ({ panel: panelRef }), [panelRef]); @@ -42,11 +43,13 @@ const DialogWrap: React.FC = (props) => { React.useEffect(() => { if (visible) { setAnimatedVisible(true); + hasOpenedRef.current = true; } }, [visible]); // Destroy on close will remove wrapped div - if (!forceRender && destroyOnHidden && !animatedVisible) { + // Use `hasOpenedRef` to check if component has ever been opened (after animation completes) + if (destroyOnHidden && hasOpenedRef.current && !visible && !animatedVisible) { return null; } diff --git a/tests/index.spec.tsx b/tests/index.spec.tsx index dcb33153..438a4a77 100644 --- a/tests/index.spec.tsx +++ b/tests/index.spec.tsx @@ -158,6 +158,32 @@ describe('dialog', () => { expect(document.querySelector('.test-input')).toHaveValue(''); }); + + it('should destroy even when forceRender is true', () => { + const Demo: React.FC> = (props) => ( + + + + ); + + const { rerender } = render(); + + // Force render, but not visible yet - should still render (forceRender) + expect(document.querySelectorAll('.test-force-destroy')).toHaveLength(1); + + // Show + rerender(); + act(() => { + jest.runAllTimers(); + }); + + // Hide - should destroy because destroyOnHidden is true + rerender(); + act(() => { + jest.runAllTimers(); + }); + expect(document.querySelectorAll('.test-force-destroy')).toHaveLength(0); + }); }); it('esc to close', () => {