-
-
Notifications
You must be signed in to change notification settings - Fork 563
fix: resolve hydration issues in editor and root layout #250
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
@ChinaShrimp is attempting to deploy a commit to the tweakcn OSS program Team on Vercel. A member of the Team first needs to authorize it. |
WalkthroughThis change adds hydration warning suppression to the root layout's HTML element and introduces a mounting state guard to the undo-redo buttons component via a React hook that prevents rendering until after client-side mount. Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~8 minutes
Possibly related PRs
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
components/editor/action-bar/components/undo-redo-buttons.tsx (1)
11-15: LGTM! Standard pattern for preventing hydration mismatches.The mounted guard ensures both server and client render with
mounted=falseinitially, preventing hydration errors from localStorage-based state. After mount, the component re-renders with the correct client-side state.💡 Consider extracting to a reusable hook
Since the mounted guard pattern may be needed elsewhere, consider extracting it:
Create a new file
hooks/use-mounted.ts:import { useEffect, useState } from "react"; export function useMounted() { const [mounted, setMounted] = useState(false); useEffect(() => { setMounted(true); }, []); return mounted; }Then use it in this component:
- const [mounted, setMounted] = React.useState(false); - - React.useEffect(() => { - setMounted(true); - }, []); + const mounted = useMounted();
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
app/layout.tsxcomponents/editor/action-bar/components/undo-redo-buttons.tsx
🔇 Additional comments (4)
components/editor/action-bar/components/undo-redo-buttons.tsx (3)
5-5: LGTM!Import of React namespace is necessary for the
useStateanduseEffecthooks used below.
7-7: Minor formatting adjustment.The spacing change in the interface declaration doesn't affect functionality.
23-23: LGTM! Correctly prevents hydration mismatch.Both buttons now check
!mountedin addition to existing conditions. This ensures they render as disabled on both server and client initial render, then enable after mount based on actual localStorage state.The UX will show a brief disabled state before enabling (if undo/redo history exists), which is expected and preferable to hydration errors.
Also applies to: 35-35
app/layout.tsx (1)
56-56: The dualsuppressHydrationWarningattributes are redundant; consolidate to the script tag only.The ThemeScript component already has
suppressHydrationWarningon the<script>tag itself (line 100 in components/theme-script.tsx), which addresses the specific hydration mismatch caused by the inline script modifying CSS variables before React hydrates. The additionalsuppressHydrationWarningon the root<html>element (line 56) is unnecessarily broad and could mask other hydration issues.Remove the suppression from the
<html>tag and rely solely on the script tag's suppression, which targets the actual source of the mismatch. If you keep the root-level suppression, add a comment explaining why it's necessary beyond the script tag's own suppression.
This PR addresses two hydration mismatch errors encountered during development and debugging.
Fix Root Layout Hydration Mismatch
The ThemeScript component injects inline styles (CSS variables) into the tag at runtime to prevent FOUC (Flash of Unstyled Content). This caused a mismatch because the server-rendered tag did not contain these styles, while the client-side tag did immediately after hydration.
Fix Editor Undo/Redo Buttons Hydration Mismatch
The UndoRedoButtons component relies on useEditorStore which persists state to localStorage.
Server-side: Local storage is unavailable, so the undo/redo history is empty, rendering the buttons as disabled.
Client-side: The store hydrates from localStorage, restoring history and potentially rendering the buttons as enabled.
This difference caused a hydration error.
Summary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings.