fix(qr): useState для containerEl, чтобы effect запускался после монтирования DialogContent

This commit is contained in:
2026-07-07 21:17:27 +03:00
parent 1f5ecb6da4
commit fc8e85832c

View File

@@ -96,7 +96,7 @@ export function QrScannerButton({ className }: QrScannerButtonProps) {
const [open, setOpen] = useState(false);
const [, navigate] = useLocation();
const scannerRef = useRef<Html5Qrcode | null>(null);
const containerRef = useRef<HTMLDivElement | null>(null);
const [containerEl, setContainerEl] = useState<HTMLDivElement | null>(null);
const [error, setError] = useState<string | null>(null);
const [isStarting, setIsStarting] = useState(false);
const [retryKey, setRetryKey] = useState(0);
@@ -318,14 +318,14 @@ export function QrScannerButton({ className }: QrScannerButtonProps) {
);
useEffect(() => {
if (!open || !containerRef.current) return;
if (!open || !containerEl) return;
cancelledRef.current = false;
setIsStarting(true);
setError(null);
setMode('library');
const container = containerRef.current;
const container = containerEl;
container.innerHTML = '';
// Let the dialog content finish rendering / layout before accessing camera.
@@ -374,14 +374,14 @@ export function QrScannerButton({ className }: QrScannerButtonProps) {
clearTimeout(startTimeout);
stopAll();
};
}, [open, retryKey, startLibrary, startNative, presentError, stopAll, log]);
}, [open, containerEl, retryKey, startLibrary, startNative, presentError, stopAll, log]);
function handleScanFromFile() {
let scanner = scannerRef.current;
const needsScanner = !scanner;
if (needsScanner) {
const container = containerRef.current;
const container = containerEl;
if (!container) return;
const scannerId = 'qr-scanner-file-' + Date.now();
container.id = scannerId;
@@ -455,7 +455,7 @@ export function QrScannerButton({ className }: QrScannerButtonProps) {
</DialogHeader>
<div className="relative">
<div
ref={containerRef}
ref={setContainerEl}
className="w-full min-h-[300px] aspect-square rounded overflow-hidden bg-black [&_video]:w-full [&_video]:h-full [&_video]:object-cover"
/>
{isStarting && !error && (