sopt-makers / sopt.org-frontend

대학생 연합 IT벤처창업 동아리 SOPT 공식 홈페이지
https://sopt.org/
MIT License
24 stars 7 forks source link

[Refactor] memberInfo RQ에서 SSG fetching으로 수정 #419

Closed eonseok-jeon closed 1 month ago

eonseok-jeon commented 1 month ago

죄송합니다 실수로 주용이 PR을 잘못 머지해서 다시 복구시켰어요ㅜ 기존 pr

Summary

close #415

Comment

일단 기존에 useGetMember 쿼리 커스텀 훅으로 members 데이터를 받아왔었습니다.

const { data } = useGetMember();

const cardContent = useMemo(() => {
    if (!isLoading)
      return (data ? data.members : emptyMembers(6)).map(
        ({
          id,
          name,
          position,
          description,
          currentProject,
          imageSrc,
          gmail,
          linkedin,
          github,
        }) => (
          <MemberCard
            key={id}
            name={name}
            position={position}
            description={description}
            currentProject={currentProject}
            imageSrc={imageSrc}
            gmail={gmail}
            linkedin={linkedin}
            github={github}
          />
        ),
      );

    return (
      <St.OvalSpinnerWrapper>
        <OvalSpinner />
      </St.OvalSpinnerWrapper>
    );
  }, [data, isLoading]);

사실 서버 컴포넌트의 이점을 살릴 수 있는 NextJS에서 useQuery를 통해 클라이언트 사이드 렌더링을 하는 것보다 기존의 aboutInfogetStaticProps를 통해 prefetch 하였던 것처럼 memberInfo 데이터 또한 사전에 생성하여 props로 건내주는 방식으로 리팩토링하였습니다.

import { Suspense } from 'react';
import Flex from '@src/components/common/Flex';
import OvalSpinner from '@src/components/common/OvalSpinner';
import { MemberType } from '@src/lib/types/about';
import MemberCard from '@src/views/AboutPage/components/Member/Card';
import SectionTop from '../../@common/SectionTop';
import * as St from './style';

type MemberSectionProps = {
  generation: number;
  members: MemberType[];
};

const MemberSection = ({ generation, members }: MemberSectionProps) => {
  return (
    <Flex
      dir="column"
      gap={{ mobile: 24, tablet: 48, desktop: 60 }}
      style={{ position: 'relative' }}
    >
      <St.MarginTop />
      <SectionTop
        engTitle="Executives"
        korTitle={`${generation}기 임원진`}
        description="200명의 활동 회원들이 열정을 외칠 수 있도록, 35기 AND SOPT를 이끄는 임원진들이에요."
      />
      {/* TODO : 서버에서 description을 받아오도록 수정 */}
      <Flex
        dir="column"
        gap={{ mobile: 18, tablet: 24, desktop: 48 }}
        style={{ alignItems: 'center' }}
      >
        <Suspense
          fallback={
            <St.OvalSpinnerWrapper>
              <OvalSpinner />
            </St.OvalSpinnerWrapper>
          }
        >
          {/* {errorContent} */}
          <St.CardContainer>
            {members.map(
              ({
                id,
                name,
                position,
                description,
                currentProject,
                imageSrc,
                gmail,
                linkedin,
                github,
              }) => (
                <MemberCard
                  key={id}
                  name={name}
                  position={position}
                  description={description}
                  currentProject={currentProject}
                  imageSrc={imageSrc}
                  gmail={gmail}
                  linkedin={linkedin}
                  github={github}
                />
              ),
            )}
          </St.CardContainer>
        </Suspense>
      </Flex>
    </Flex>
  );
};

export default MemberSection;

기존에 사용하던 MemberContent 컴포넌트를 그대로 사용할 수 있었지만, 불필요하게 props를 전달하는 것 같아서 Section 컴포넌트에서 렌더링하도록 하였습니다.

또한 Suspense로 감싸주어 서버에서 미리 청크를 분리하고 데이터가 준비되는대로 클라이언트로 전송할 수 있도록 구현하였습니다.

아직은 MemberContent 컴포넌트를 삭제하지는 않았는데, 현재 변경사항이 반영된다면 어느곳에서도 사용하지 않으니 삭제하도록 하겠습니다.

height[bot] commented 1 month ago

Link Height tasks by mentioning a task ID in the pull request title or commit messages, or description and comments with the keyword link (e.g. "Link T-123").

💡Tip: You can also use "Close T-X" to automatically close a task when the pull request is merged.