Unmount Dialog children when closed
The native <dialog> wrapper rendered its children unconditionally and only called dialog.close() on the underlying element when open went false. The React subtree stayed mounted, so component state (e.g. a ConfirmButton mid-confirm with a red checkmark showing) survived a close/reopen cycle and reappeared the next time the user opened the same dialog. Gate children on open so the subtree unmounts on close. Next open gets a fresh tree with default state.
This commit is contained in:
@@ -38,6 +38,22 @@ describe("Dialog", () => {
|
|||||||
expect(dialog?.hasAttribute("open")).toBe(false);
|
expect(dialog?.hasAttribute("open")).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("unmounts children when closed so internal state does not persist", () => {
|
||||||
|
const { rerender } = render(
|
||||||
|
<Dialog open={true} onClose={() => {}}>
|
||||||
|
<span>Body</span>
|
||||||
|
</Dialog>,
|
||||||
|
);
|
||||||
|
expect(screen.queryByText("Body")).not.toBeNull();
|
||||||
|
|
||||||
|
rerender(
|
||||||
|
<Dialog open={false} onClose={() => {}}>
|
||||||
|
<span>Body</span>
|
||||||
|
</Dialog>,
|
||||||
|
);
|
||||||
|
expect(screen.queryByText("Body")).toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
it("calls onClose on cancel event", () => {
|
it("calls onClose on cancel event", () => {
|
||||||
const onClose = vi.fn();
|
const onClose = vi.fn();
|
||||||
render(
|
render(
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ export function Dialog({ open, onClose, className, children }: DialogProps) {
|
|||||||
className,
|
className,
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<div className="p-6">{children}</div>
|
{open ? <div className="p-6">{children}</div> : null}
|
||||||
</dialog>
|
</dialog>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user