fix: React error #310 — useMemo after early return in detail panel

Move threadChain useMemo before the `if (!entry) return null` early
return to keep hook call order stable between renders. When entry was
null, the hook was skipped, causing "Rendered more hooks than during
the previous render" crash on subsequent renders with entry set.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
AI Assistant
2026-03-12 00:23:15 +02:00
parent 0cc14a96e9
commit d8a10fadc0
@@ -177,26 +177,16 @@ export function RegistryEntryDetail({
setTimeout(() => setCopiedPath(null), 2000);
}, []);
if (!entry) return null;
const dir = DIRECTION_CONFIG[entry.direction] ?? DIRECTION_CONFIG.intrat;
const DirIcon = dir.icon;
const status = STATUS_CONFIG[entry.status] ?? STATUS_CONFIG.deschis;
const overdueDays =
entry.status === "deschis" ? getOverdueDays(entry.deadline) : null;
const isOverdue = overdueDays !== null && overdueDays > 0;
const threadParent = entry.threadParentId
// Build full chain for mini flow diagram (must be before early return to keep hook order stable)
const threadChain = useMemo(() => {
if (!entry) return [];
const threadParentEntry = entry.threadParentId
? allEntries.find((e) => e.id === entry.threadParentId)
: null;
const threadChildren = allEntries.filter(
const threadChildEntries = allEntries.filter(
(e) => e.threadParentId === entry.id,
);
// Build full chain for mini flow diagram
const threadChain = useMemo(() => {
if (!threadParent && threadChildren.length === 0) return [];
if (!threadParentEntry && threadChildEntries.length === 0) return [];
const byId = new Map(allEntries.map((e) => [e.id, e]));
// Walk up to root
let root = entry;
@@ -222,7 +212,24 @@ export function RegistryEntryDetail({
}
chain.sort((a, b) => a.date.localeCompare(b.date));
return chain;
}, [entry, threadParent, threadChildren, allEntries]);
}, [entry, allEntries]);
if (!entry) return null;
const dir = DIRECTION_CONFIG[entry.direction] ?? DIRECTION_CONFIG.intrat;
const DirIcon = dir.icon;
const status = STATUS_CONFIG[entry.status] ?? STATUS_CONFIG.deschis;
const overdueDays =
entry.status === "deschis" ? getOverdueDays(entry.deadline) : null;
const isOverdue = overdueDays !== null && overdueDays > 0;
const threadParent = entry.threadParentId
? allEntries.find((e) => e.id === entry.threadParentId)
: null;
const threadChildren = allEntries.filter(
(e) => e.threadParentId === entry.id,
);
return (
<Sheet open={open} onOpenChange={onOpenChange}>