글 작성자: 망고좋아
반응형

📖 오늘 배운 내용 - 2022.02.18

  • 그래프 페이지, 랭킹 페이지 버그 및 css 수정
  • 랭킹 페이지 스켈레톤 ui 적용

 

📝 스켈레톤 ui 적용

  • 이렇게 초기 로드 시 ui가 깨지는 현상을 발생했다.
  • 저 부분을 스피너를 이용해 로딩 중이라는 것을 보여주려고 했지만 ui측면에서는 스피너보다 스켈레톤 ui가 사용자 측면에서 적합하다고 생각해서 도입하기로 결정했다.
  • 직접 만들 수 있겠지만 시간이 부족해서 react-content-loader를 설치해서 사용하기로 결정했다.
npm i react-content-loader

 

📕 적용 코드

🛠 Skeleton/index.js

import React from "react";
import ContentLoader from "react-content-loader";
import * as Skeletons from "./style";

function Skeleton() {
  return (
    <Skeletons.Container>
      <ContentLoader
        speed={0.5}
        width={200}
        height={60}
        backgroundColor="#e3e3e3"
        foregroundColor="#d6d6d6"
      >
        <rect x="95" y="20" rx="3" ry="3" width="88" height="8" />
        <rect x="95" y="36" rx="3" ry="3" width="52" height="6" />
        <circle cx="54" cy="30" r="20" />
      </ContentLoader>
    </Skeletons.Container>
  );
}

export default Skeleton;

 

🛠 Skeleton/style.js

/* eslint-disable*/
import styled from "styled-components";

export const Container = styled.div`
  width: 349px;
  margin-top: 32px;
  padding: 17px 35px;
  border-radius: 10px;
  background: #ffffff;
  position: relative;

  @media ${({ theme }) => theme.device.laptop} {
    width: 430px;
  }
`;

 

🛠 rank.index.js

import React, { useEffect, useState } from "react";
import { Container } from "@/components/Container/style";
import * as api from "@/api";
import RankTitle from "./RankTitle";
import Rank from "./Rank";
import * as Ranks from "./style";
import Skeletons from "./Skeleton";

function RankPage() {
  const [myRank, setMyRank] = useState({});
  const [userRank, setUserRank] = useState([]);
  const [loading, setLoading] = useState(false);

  const getRank = async () => {
    setLoading(true);
    const rankData = await api.getRank();

    if (rankData.success) {
      setMyRank(rankData.data.myRank);
      setUserRank(rankData.data.userRank);
    } else {
      setMyRank(null);
    }
    setLoading(false);
  };

  useEffect(() => {
    getRank();
  }, []);

  return (
    <Container>
      <RankTitle />
      {myRank ? (
        <Ranks.ResponsiveDiv>
          {loading ? (
            <Skeletons />
          ) : (
            <Rank
              myRanking
              imgURL={myRank.avatarUrl}
              id={myRank.username}
              point={myRank.totalScore}
              rank={myRank.rank}
            />
          )}
          {loading ? (
            <Ranks.ResponsivUserRankWrapper>
              <Skeletons />
              <Skeletons />
              <Skeletons />
            </Ranks.ResponsivUserRankWrapper>
          ) : (
            <Ranks.ResponsivUserRankWrapper>
              {userRank.length ? (
                userRank.map((it, idx) =>
                  idx <= 9 ? (
                    <Rank
                      key={`${it.username}-${it.rank}-${it.totalScore}`}
                      imgURL={it.avatarUrl}
                      id={it.username}
                      point={it.totalScore}
                      rank={it.rank}
                    />
                  ) : (
                    ""
                  ),
                )
              ) : (
                <Ranks.NoData>데이터가 없습니다.</Ranks.NoData>
              )}
            </Ranks.ResponsivUserRankWrapper>
          )}
        </Ranks.ResponsiveDiv>
      ) : (
        <Ranks.NoData>데이터가 없습니다.</Ranks.NoData>
      )}
    </Container>
  );
}
export default RankPage;

 

 

💡 오늘 깨달은 것

  • 로딩 시간이 3초 이상일 때 약 30%, 5초 이상은 약 90% 이상의 유저가 사이트 이탈한다고 한다. 상황에 맞게 스피너를 사용하거나 스켈레톤 ui를 사용해야 한다. 랭크 페이지 같은 경우 스피너보다 스켈레톤이 적합하다고 판단하고 적용했다. 개발하고 나서 해당 페이지의 첫인상과 기다림의 답답함이 조금이나마 사라졌다.
  • 사용자 입장을 생각하고 어떤 ui가 적합한지 판단하여 잘 선택해보자!
  • localhost라는 단어가 등장하는 곳은 엔진엑스 말고는 없어야 한다.
  • tag는 커밋 단위로 달아 놓고 tag명은 릴리즈 버전명으로 작성!
  • 프론트에서 .env 파일을 사용하려면 플러그인을 설치해줘야 한다.
    • 하지만 cra로 하면 이런 작업은 필요 없다. 안에 다 있기 때문에 ㅋㅋ
  • 오피스아워를 통해 진짜 코치님들은 모르는 게 없다. 이런 에러를 가지고 있습니다... 하면 금방금방 해결해주신다 ㅎㅎㅎㅎ 하루 종일 삽질했던 문제들도 10분이면 해결! ㅋ 최고! ㅠㅠ

 

📌 참고

반응형