본문 바로가기
TIL

icon suspense lazy 기능으로 넣기

by 은지:) 2024. 7. 2.
728x90
반응형

 

 

vite 환경

import svgr from 'vite-plugin-svgr';

vite.config.ts에 svgr() 추가함

 

이거 안 쓰면 컴포넌트 감싸서 가져와야 됨

 

나의 구조....

 

import { Suspense, lazy, memo } from 'react';
import Loading from './Loading';
import { IconProps } from './types';
import S from './styles';

const Icon = memo(
  ({
    fileName,
    alt = 'image',
    width = '100%',
    height = '100%',
    handleClick,
  }: IconProps) => {
    const LazyComponent = lazy(() =>
      import(`./elements/${fileName}.svg`)
        .then((module) => ({
          default: () => (
            <img
              onClick={handleClick}
              src={module.default}
              style={{ width, height }}
            />
          ),
        }))
        .catch(() => ({
          default: () => (
            <S.FailImg size={{ width, height }}>
              {alt} <br />
              이미지
            </S.FailImg>
          ),
        })),
    );

    return (
      <Suspense fallback={<Loading width={width} height={height} />}>
        <LazyComponent />
      </Suspense>
    );
  },
);

export default Icon;

 

import styled, { keyframes } from 'styled-components';

const Loading = ({ width = '100%', height = '100%' }) => {
  return (
    <LoadingSpinner size={{ width, height }}>
      <Spinner className="spinner"></Spinner>
    </LoadingSpinner>
  );
};

export default Loading;

const LoadingSpinner = styled.div<{ size: { width: string; height: string } }>`
  display: flex;
  justify-content: center;
  align-items: center;
  width: ${({ size }) => size.width};
  height: ${({ size }) => size.height};
`;

const spin = keyframes`
  to {
    transform: rotate(360deg);
  }
`;

const Spinner = styled.div`
  border: 4px solid rgba(0, 0, 0, 0.1);
  width: 50%;
  height: 50%;
  border-radius: 50%;
  border-left-color: #09f;
  animation: ${spin} 1s ease infinite;
`;

 

 

아이콘을 로딩하기 전 스피너, 아이콘 로딩 실패시 보여줄 수 있는 UI의 장점도 있지만

무엇보다 icon 을 모두 저 컴포넌트 안에서 해결할 수 있어서 좋은 거 같다

 

icon 쓸 때마다 이름만 넘겨주면 import도 저 컴포넌트 안에서 동적으로 가능하고...

관심사 잘 모은 거 같아서 뿌듯쓰

 

728x90
반응형

'TIL' 카테고리의 다른 글

타입스크립트의 추론  (1) 2024.07.20
새로 나온 hook useFormStatus 등 리액트 동향 살펴보기  (0) 2024.07.02
vite와 swc  (1) 2024.06.30
ts 브랜딩 타입 (태그드 타입) vs enum vs 리터럴  (0) 2024.06.28
jest  (0) 2024.06.26

댓글