fix(pwa): stop calendar remount/flash on re-render (Bug B root cause)
The calendar flashed whenever the event popup/form closed or a post-write events refetch landed. Root cause: CalendarContent was a function component DEFINED INSIDE CalendarShell's render and used as <CalendarContent />. A nested component has a new identity every render, so React unmounted+remounted its whole subtree — including <ScheduleXCalendar> — on ANY CalendarShell re-render. The earlier Bug B work only minimized re-renders (Zustand selectors) to dodge this; the resync-before-done fix made the post-write ['events'] refetch deliver changed data again, so the remount/flash returned. Fix: render the content as a plain JSX element value (const calendarContent) referenced at both layout sites instead of a nested component type. Element values reconcile in place across re-renders — no remount, no flash.
This commit is contained in:
@@ -236,9 +236,15 @@ export function CalendarShell() {
|
|||||||
|
|
||||||
// ── Calendar content ───────────────────────────────────────────────────────
|
// ── Calendar content ───────────────────────────────────────────────────────
|
||||||
|
|
||||||
// The content panel (right of sidebar on desktop, full-width on phone)
|
// The content panel (right of sidebar on desktop, full-width on phone).
|
||||||
function CalendarContent() {
|
//
|
||||||
return (
|
// This is a plain JSX value, NOT a nested `function CalendarContent()` rendered
|
||||||
|
// as `<CalendarContent />`. A component defined inside render has a new identity
|
||||||
|
// every render, so React unmounts+remounts its entire subtree — including
|
||||||
|
// <ScheduleXCalendar> — on ANY CalendarShell re-render (popup/form close, post-
|
||||||
|
// write events refetch). That full remount is the "calendar flash" (Bug B). As
|
||||||
|
// an element value it reconciles in place across re-renders: no remount, no flash.
|
||||||
|
const calendarContent = (
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
flex: 1,
|
flex: 1,
|
||||||
@@ -330,8 +336,7 @@ export function CalendarShell() {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
|
||||||
|
|
||||||
// ── Full layout ────────────────────────────────────────────────────────────
|
// ── Full layout ────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
@@ -355,7 +360,7 @@ export function CalendarShell() {
|
|||||||
currentUserName={meQuery.data?.user.displayName ?? undefined}
|
currentUserName={meQuery.data?.user.displayName ?? undefined}
|
||||||
/>
|
/>
|
||||||
<InstallPrompt />
|
<InstallPrompt />
|
||||||
<CalendarContent />
|
{calendarContent}
|
||||||
<EventDetailPopover />
|
<EventDetailPopover />
|
||||||
|
|
||||||
{/* New Event FAB — phone: bottom-right floating action button (UI-SPEC §Interaction Contract) */}
|
{/* New Event FAB — phone: bottom-right floating action button (UI-SPEC §Interaction Contract) */}
|
||||||
@@ -457,7 +462,7 @@ export function CalendarShell() {
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<CalendarContent />
|
{calendarContent}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* EventDetailPopover — standalone mode driven by Zustand openEventId */}
|
{/* EventDetailPopover — standalone mode driven by Zustand openEventId */}
|
||||||
|
|||||||
Reference in New Issue
Block a user