Skip to content

Commit baa02f7

Browse files
Fix blurrable image visibility init
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
1 parent 606569b commit baa02f7

File tree

2 files changed

+29
-16
lines changed

2 files changed

+29
-16
lines changed

app/components/blurrable-image.tsx

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ import { clsx } from 'clsx'
22
import * as React from 'react'
33

44
const isServer = typeof document === 'undefined'
5+
const useIsomorphicLayoutEffect = isServer
6+
? React.useEffect
7+
: React.useLayoutEffect
58

69
function BlurrableImage({
710
img,
@@ -12,37 +15,40 @@ function BlurrableImage({
1215
blurDataUrl?: string
1316
} & React.HTMLAttributes<HTMLDivElement>) {
1417
const id = React.useId()
15-
const [visible, setVisible] = React.useState(() => {
16-
if (isServer) return false
17-
18-
// on the client, it's possible the images has already finished loading.
19-
// we've got the data-evt-onload attribute on the image
20-
// (which our entry.server replaces with simply "onload") which will remove
21-
// the class "opacity-0" from the image once it's loaded. So we'll check
22-
// if the image is already loaded and if so, we know that visible should
23-
// initialize to true.
24-
const el = document.getElementById(id)
25-
return el instanceof HTMLImageElement && !el.classList.contains('opacity-0')
26-
})
18+
const [visible, setVisible] = React.useState(false)
2719
const jsImgElRef = React.useRef<HTMLImageElement>(null)
2820

21+
useIsomorphicLayoutEffect(() => {
22+
const imageEl = jsImgElRef.current
23+
if (!imageEl) return
24+
25+
// On the client, the image might have already loaded before hydration,
26+
// which removes the opacity class via the server-rendered onload handler.
27+
if (imageEl.complete || !imageEl.classList.contains('opacity-0')) {
28+
setVisible(true)
29+
}
30+
}, [])
31+
2932
React.useEffect(() => {
30-
if (!jsImgElRef.current) return
31-
if (jsImgElRef.current.complete) {
33+
const imageEl = jsImgElRef.current
34+
if (!imageEl) return
35+
if (imageEl.complete) {
3236
setVisible(true)
3337
return
3438
}
3539

3640
let current = true
37-
jsImgElRef.current.addEventListener('load', () => {
41+
const handleLoad = () => {
3842
if (!jsImgElRef.current || !current) return
3943
setTimeout(() => {
4044
setVisible(true)
4145
}, 0)
42-
})
46+
}
47+
imageEl.addEventListener('load', handleLoad)
4348

4449
return () => {
4550
current = false
51+
imageEl.removeEventListener('load', handleLoad)
4652
}
4753
}, [])
4854

pr-description.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
## Summary
2+
-
3+
4+
## Testing
5+
-
6+
7+
Fixes KCD-NODE-VB

0 commit comments

Comments
 (0)