From 408433a7fbd9663f00347ab39048fcba8ae6d8ad Mon Sep 17 00:00:00 2001 From: jinsoo Date: Tue, 26 Aug 2025 00:23:12 +0900 Subject: [PATCH] fix: improve image loading state handling with useRef and complete check --- .changeset/tough-shrimps-spend.md | 5 +++++ .../src/components/Cover/index.tsx | 18 ++++++++++++++++-- .../Renderer/components/Image/Image.tsx | 18 ++++++++++++++++-- 3 files changed, 37 insertions(+), 4 deletions(-) create mode 100644 .changeset/tough-shrimps-spend.md diff --git a/.changeset/tough-shrimps-spend.md b/.changeset/tough-shrimps-spend.md new file mode 100644 index 0000000..a19a733 --- /dev/null +++ b/.changeset/tough-shrimps-spend.md @@ -0,0 +1,5 @@ +--- +"notion-to-jsx": patch +--- + +improve image loading state handling with useRef and complete check diff --git a/packages/notion-to-jsx/src/components/Cover/index.tsx b/packages/notion-to-jsx/src/components/Cover/index.tsx index 77d3a38..f91268e 100644 --- a/packages/notion-to-jsx/src/components/Cover/index.tsx +++ b/packages/notion-to-jsx/src/components/Cover/index.tsx @@ -1,4 +1,4 @@ -import { useState } from 'react'; +import { useState, useRef, useEffect } from 'react'; import { coverContainer, skeletonWrapper, imageStyle } from './styles.css'; import Skeleton from '../Skeleton'; @@ -13,6 +13,19 @@ interface Props { */ const Cover = ({ src, alt }: Props) => { const [isLoaded, setIsLoaded] = useState(false); + const imgRef = useRef(null); + + // 이미지가 이미 로드된 경우를 체크 + useEffect(() => { + const img = imgRef.current; + if (img && img.complete && img.naturalHeight !== 0) { + setIsLoaded(true); + } + }, [src]); + + const handleLoad = () => { + setIsLoaded(true); + }; return (
@@ -20,10 +33,11 @@ const Cover = ({ src, alt }: Props) => {
{alt} setIsLoaded(true)} + onLoad={handleLoad} loading="lazy" /> diff --git a/packages/notion-to-jsx/src/components/Renderer/components/Image/Image.tsx b/packages/notion-to-jsx/src/components/Renderer/components/Image/Image.tsx index 206c202..ef20ad1 100644 --- a/packages/notion-to-jsx/src/components/Renderer/components/Image/Image.tsx +++ b/packages/notion-to-jsx/src/components/Renderer/components/Image/Image.tsx @@ -1,4 +1,4 @@ -import { useState } from 'react'; +import { useState, useRef, useEffect } from 'react'; import { MemoizedRichText } from '../MemoizedComponents'; import { imageContainer, @@ -42,6 +42,19 @@ const Image = ({ isColumn = false, }: Props) => { const [isLoaded, setIsLoaded] = useState(false); + const imgRef = useRef(null); + + // 이미지가 이미 로드된 경우를 체크 + useEffect(() => { + const img = imgRef.current; + if (img && img.complete && img.naturalHeight !== 0) { + setIsLoaded(true); + } + }, [src]); + + const handleLoad = () => { + setIsLoaded(true); + }; return (
@@ -50,6 +63,7 @@ const Image = ({
{alt} setIsLoaded(true)} + onLoad={handleLoad} width={format?.block_width} height={format?.block_height} style={getImageTagStyle(format)}