fix(ui): hydration mismatch su /tracking e /plan (date calcolate client-side)
I React errors #418/#423/#425 segnalati dal browser nel flow di salvataggio check-in: l'HTML server-rendered divergeva dal client-rendered, causando `Text content does not match`. La submit del check-in falliva silenziosamente. Cause: - `weight-entry-form.tsx` calcolava `todayISO()` (basato su `new Date()`) dentro `defaultValues` di `useForm`. Il render avviene sia SSR che hydration, e fra i due il valore può differire (anche di pochi ms attraverso la mezzanotte locale, oppure per fuso orario server vs client). - `plan-week.tsx` con `todayDayOfWeek()` aveva lo stesso problema sul pannello macros. Fix: il valore viene calcolato server-side nel rispettivo Server Component (`tracking/page.tsx`, `plan/page.tsx`) e passato come prop al Client Component. Stabile attraverso SSR e hydration perché serializzato nell'HTML iniziale. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
f7f6410559
commit
221b567d45
4 files changed
+33
-18
No files matched your search
@@ -38,11 +38,16 @@ export default async function TrackingPage({ params: { locale } }: { params: { l
|
||||
fetchTodayCheckIn(),
|
||||
]);
|
||||
|
||||
// Calcolato server-side per evitare hydration mismatch su WeightEntryForm.
|
||||
const now = new Date();
|
||||
const todayISO = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')}`;
|
||||
|
||||
return (
|
||||
<TrackingPageContent
|
||||
entries={entries}
|
||||
profile={profile as ProfileLike}
|
||||
todayCheckIn={todayCheckIn}
|
||||
todayISO={todayISO}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -51,10 +56,12 @@ function TrackingPageContent({
|
||||
entries,
|
||||
profile,
|
||||
todayCheckIn,
|
||||
todayISO,
|
||||
}: {
|
||||
entries: Awaited<ReturnType<typeof fetchWeightEntries>>;
|
||||
profile: ProfileLike;
|
||||
todayCheckIn: Awaited<ReturnType<typeof fetchTodayCheckIn>>;
|
||||
todayISO: string;
|
||||
}) {
|
||||
const t = useTranslations('Tracking');
|
||||
const latest = entries[0] ?? null;
|
||||
@@ -135,7 +142,7 @@ function TrackingPageContent({
|
||||
<div className="relative grid gap-12 md:grid-cols-12">
|
||||
<section className="animate-fade-up [animation-delay:300ms] md:col-span-7">
|
||||
<p className="editorial-eyebrow mb-6">{t('newEntry')}</p>
|
||||
<WeightEntryForm latest={latest} />
|
||||
<WeightEntryForm latest={latest} todayISO={todayISO} />
|
||||
</section>
|
||||
<aside className="md:border-ink/15 animate-fade-up [animation-delay:420ms] md:col-span-5 md:border-l md:pl-10">
|
||||
<p className="editorial-eyebrow mb-6">{t('history')}</p>
|
||||
|
||||
Reference in new issue
Block a user