fix: move useEffect hook to top level to comply with Rules of Hooks

- Move OG image fetching useEffect to component top level
- Make hook logic conditional instead of hook call itself
- Prevents 'Rendered more hooks than during previous render' error
- Remove duplicate firstUrlClassification declaration
This commit is contained in:
Gigi
2025-10-03 10:26:40 +02:00
parent 3d6403f139
commit 796380ea0d

View File

@@ -32,6 +32,16 @@ export const BookmarkItem: React.FC<BookmarkItemProps> = ({ bookmark, index, onS
// Extract URLs from bookmark content
const extractedUrls = extractUrlsFromContent(bookmark.content)
const hasUrls = extractedUrls.length > 0
const firstUrl = hasUrls ? extractedUrls[0] : null
const firstUrlClassification = firstUrl ? classifyUrl(firstUrl) : null
// Fetch OG image for large view (hook must be at top level)
const instantPreview = firstUrl ? getPreviewImage(firstUrl, firstUrlClassification?.type || '') : null
React.useEffect(() => {
if (viewMode === 'large' && firstUrl && !instantPreview && !ogImage) {
fetchOgImage(firstUrl).then(setOgImage)
}
}, [viewMode, firstUrl, instantPreview, ogImage])
const contentLength = (bookmark.content || '').length
const shouldTruncate = !expanded && contentLength > 210
@@ -75,9 +85,6 @@ export const BookmarkItem: React.FC<BookmarkItemProps> = ({ bookmark, index, onS
}
}
// Get classification for the first URL (for the main button)
const firstUrlClassification = hasUrls ? classifyUrl(extractedUrls[0]) : null
// Compact view rendering
if (viewMode === 'compact') {
const handleCompactClick = () => {
@@ -126,17 +133,8 @@ export const BookmarkItem: React.FC<BookmarkItemProps> = ({ bookmark, index, onS
// Large preview view rendering
if (viewMode === 'large') {
const firstUrl = hasUrls ? extractedUrls[0] : null
const instantPreview = firstUrl ? getPreviewImage(firstUrl, firstUrlClassification?.type || '') : null
const previewImage = instantPreview || ogImage
// Fetch OG image for non-YouTube URLs
React.useEffect(() => {
if (firstUrl && !instantPreview && !ogImage) {
fetchOgImage(firstUrl).then(setOgImage)
}
}, [firstUrl, instantPreview, ogImage])
return (
<div key={`${bookmark.id}-${index}`} className={`individual-bookmark large ${bookmark.isPrivate ? 'private-bookmark' : ''}`}>
{hasUrls && (