요가나라 게시판의 게시물 클릭 시 react-query
로 캐싱된 데이터 때문에 이전 데이터가 잠깐 비치는 현상이 발생하고 있다. 그래서 새로운 데이터가 fetching되는 동안 스켈레톤 컴포넌트를 적용해주려고 한다. 유용하게도 css와 애니메이션을 제공해주는 라이브러리가 있었다.
스켈레톤 컴포넌트는 실제 들어갈 컨텐츠가 로딩되는 동안 컨텐츠가 들어갈 자리를 대신하는 빈 껍데기이다. 보통 실제 보여줄 컨텐츠와 같은 레이아웃을 사용한다.
로딩 바나 로딩 스피너와 같은 역할을 한다. 어떤 데이터가 어떤 형식으로 표기될지 사용자에게 레이아웃으로 미리 알려줌으로써 단순한 흰 화면이나 로딩 스피너 대신 시각적 즐거움을 더해줄 수 있는 사용자 친화적 UI다.
yarn add react-content-loader
react-content-loader
는 사용법이 매우 간단한데, ContentLoader로 사용자가 지정한 레이아웃을 한 번 감싸주기만 하면 끝이다. 사용자 지정 레이아웃은 rect와 circle 요소로 만들 수 있다. 요소의 색과 배경의 색도 사용자 마음대로 커스터마이징하여 지정해줄 수 있다.
import React from "react"
import ContentLoader from "react-content-loader"
const MyLoader = (props) => (
<ContentLoader
speed={2} // 속도
width={400}
height={160}
viewBox="0 0 400 160"
backgroundColor="#f3f3f3" // 배경색
foregroundColor="#b30000" // 요소 색
{...props}
>
<rect x="48" y="8" rx="3" ry="3" width="88" height="6" /> //사각형
<rect x="48" y="26" rx="3" ry="3" width="52" height="6" />
<rect x="0" y="56" rx="3" ry="3" width="410" height="6" />
<rect x="0" y="72" rx="3" ry="3" width="380" height="6" />
<rect x="0" y="88" rx="3" ry="3" width="178" height="6" />
<circle cx="20" cy="20" r="20" /> //원
</ContentLoader>
)
export default MyLoader
react-content-loader
를 사용한 스켈레톤 컴포넌트는 wrapper가 같은 코드를 공유하고 데이터가 fetching되는 모든 컴포넌트에서 사용할 예정이기 때문에 재사용성을 고려한 컴포넌트로 만들어준다.
import React from "react";
import ContentLoader from "react-content-loader";
function Skeleton(props) {
return (
<ContentLoader
speed={2}
viewBox="0 0 400 160"
backgroundColor="#f3f3f3"
foregroundColor="#ecebeb"
{...props}
>
{props.children}
</ContentLoader>
);
}
export default Skeleton;
게시물 이동 시 캐싱된 데이터의 잔상이 남는 게시글 컴포넌트에 적용해줬다.
적용 전
적용 후