refactor(mui): ConfirmDialog freezes content via derive-state-from-props (no ref-in-render)

Replaces the useRef-during-render snapshot with React's blessed 'adjust state when a prop changes' pattern (useState + guarded setState during render). Render-pure, same self-contained behavior. Avoids writing to a ref during render.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
BOHA
2026-06-06 21:09:01 +02:00
parent 16db585022
commit 81adebd63a

View File

@@ -1,4 +1,4 @@
import { useRef } from "react";
import { useState } from "react";
import Dialog from "@mui/material/Dialog";
import DialogTitle from "@mui/material/DialogTitle";
import DialogContent from "@mui/material/DialogContent";
@@ -30,11 +30,16 @@ export default function ConfirmDialog({
confirmVariant = "primary",
loading = false,
}: ConfirmDialogProps) {
// Retain the last shown title/message so the close (fade-out) transition
// doesn't flash empty when the caller clears its source data (e.g. sets the
// selected row to null) at the same moment it closes the dialog.
const shown = useRef({ title, message });
if (isOpen) shown.current = { title, message };
// Freeze the shown title/message while closing, so the fade-out transition
// never flashes empty when the caller clears its source data (e.g. sets the
// selected row to null) at the same instant it closes the dialog. This is
// React's "adjust state from props during render" pattern: update only while
// open, keep the last values once closed. (Self-contained — callers can clear
// their data on close however they like.)
const [shown, setShown] = useState({ title, message });
if (isOpen && (shown.title !== title || shown.message !== message)) {
setShown({ title, message });
}
return (
<Dialog
@@ -42,9 +47,9 @@ export default function ConfirmDialog({
onClose={loading ? undefined : onClose}
slotProps={{ paper: { sx: { borderRadius: 3 } } }}
>
<DialogTitle>{shown.current.title}</DialogTitle>
<DialogTitle>{shown.title}</DialogTitle>
<DialogContent>
<DialogContentText>{shown.current.message}</DialogContentText>
<DialogContentText>{shown.message}</DialogContentText>
</DialogContent>
<DialogActions sx={{ px: 3, pb: 2 }}>
<MuiButton onClick={onClose} color="inherit" disabled={loading}>