뭐 별거 있겠는가 ? 오랜만에 블로그를 돌면서 부족한점들을 하나하나 뜯어 고치는 도중에 눈에 들어온 그것 ..
아이고 두야
여하튼 뭐 .. 이걸 수정해야한다.
인터넷에 조금씩 찾다보니 다들 말하는 방법으로는
Image컴포넌트를 씌운 wrapper image 컴포넌트를 작성하는 것이다.
typescript'use client'
import { FC, ImgHTMLAttributes, useEffect } from 'react'
import Image from 'next/image'
import { useState } from 'react'
type FallbackImageProps = ImgHTMLAttributes<HTMLImageElement>
export const FallbackImage: FC<FallbackImageProps> = ({ src, width, height, alt, ...props }) => {
const [imgSrc, setImgSrc] = useState(src)
useEffect(() => {
setImgSrc(src)
}, [src])
return (
<Image
alt={alt ?? 'Image'}
src={imgSrc ? imgSrc : '/images/fallback.png'}
onError={() => {
setImgSrc('/images/fallback.png')
}}
{...props}
/>
)
}
근데 인터넷에 있는 방식으로하면 재미가 없지 않은가 ?
이미지태그가 여러번 박히는 페이지라고 가정하고 이상태로
휴먼 에러를 가정한다면..
그냥 페이지에서 hook을 하나 돌리게 나을 것이다.
그래서 나온게 다음 방법.
typescript'use client'
import { useEffect } from 'react'
import fallback from './seyana.jpg'
export const ImageFallbackSetter = () => {
useEffect(() => {
const images = document.querySelectorAll('img')
images.forEach((image) => {
image.onerror = () => {
image.srcset = fallback.src
image.src = fallback.src
image.onerror = null
console.log('replaced')
}
})
}, [])
return null
}
페이지 전체의 error를 싸그리 fallback으로 바꾸는
아주 혁명적인 .. 그런 방법을 사용해주자
방법 1의 경우 생성되는 각 이미지마다 useState를 돌려서 쓸모없는 자원을 낭비하는 것 같기도하고 (미쳐버린 최적화 마인드)
여러모로 .. 코드가 안이쁘다 사실 이게 본심
fallback처리 잘 해두자. 생각해보니 저번에 서버날라간 사건도 있었고 ..
지금은 아니지만 image server가 박살나는 경우에는
엑박 말고 fallback하나 띄워주면 또 이쁘게 나오지 않겠는가 ?
해피한 개발 이어나가자