9 글 목록을 띄워 줄 메인 페이지 구현하기 - 메인 페이지의 기본적인 틀 만들기

source: categories/study/gatsby/gatsby_9-00.md

메인 페이지에 사용될 컴포넌트

저희가 이번 챕터에서 구현할 컴포넌트는 총 7개로, 다음 이름을 가진 컴포넌트를 구현할 예정입니다.

  • src
    • components
      • Common
        • Footer.tsx: 페이지 하단 푸터
        • GlobalStyle.tsx: 전역 스타일
      • Main
        • CategoryList.tsx: 카테고리 목록
        • Introduction.tsx: 페이지 상단 소개글
        • PostItem.tsx: 포스트 아이템
        • PostList.tsx: 여러 포스트 아이템을 묶은 포스트 리스트
        • ProfileImage.tsx: 소개글 구역에서 사용할 프로필 이미지

디렉토리 구조는 위와 같이 설정할 것이며, 여러 페이지에서 사용되는 컴포넌트는 Common 디렉토리에 저장하고, 그 외의 컴포넌트는 각 페이지 이름의 디렉토리에 저장할 것입니다.

글로벌 스타일 정의하기

저희는 가장 먼저 전역에 적용하기 위한 글로벌 스타일을 정의하겠습니다.

이전 페이지에서 설명한 방법 그대로 활용하여 전역 스타일을 제공하는 컴포넌트를 정의해봅시다.

해당 방법이 정확하게 기억나지 않으면 이전 챕터를 다시 읽어보고 오시는 것을 추천드립니다.

지정한 스타일만 다를 뿐, 전체적인 형태는 동일하므로 설명은 생략하겠습니다.

  • src/components/Common/GlobalStyle.tsx
import React, { FunctionComponent } from 'react'
import { Global, css } from '@emotion/react'

const defaultStyle = css`
  @import url('https://fonts.googleapis.com/css2?family=Nanum+Myeongjo:wght@400;700;800&display=swap');

  * {
    padding: 0;
    margin: 0;
    box-sizing: border-box;
    font-family: 'Nanum Myeongjo', serif;
  }

  html,
  body,
  #___gatsby {
    height: 100%;
  }

  a,
  a:hover {
    color: inherit;
    text-decoration: none;
    cursor: pointer;
  }
`

const GlobalStyle: FunctionComponent = function () {
  return <Global styles={defaultStyle} />
}

export default GlobalStyle

페이지 상단 소개글 컴포넌트 구현하기

상단 소개글에 해당하는 파일인 introduction.tsx 파일을 구현해봅시다.

하지만 먼저 이 구역에서 프로필 이미지를 사용하는데, 이 프로필 이미지 부분을 따로 ProfileImage 컴포넌트로 분리해 구현해봅시다.

  • src/components/Main/ProfileImage.tsx
import React, { FunctionComponent } from 'react'
import styled from '@emotion/styled'

// 자신이 원하는 프로필 이미지 링크로 설정해주세요.
const PROFILE_IMAGE_LINK =
  'https://avatars.githubusercontent.com/u/24629040?s=460&u=0bb3411f25c0e1c5d25d753fc648739367cb7032&v=4'

const ProfileImageWrapper = styled.img`
  width: 120px;
  height: 120px;
  margin-bottom: 30px;
  border-radius: 50%;
`

const ProfileImage: FunctionComponent = function () {
  return <ProfileImageWrapper src={PROFILE_IMAGE_LINK} alt="Profile Image" />
}

export default ProfileImage

우선 이미지 링크를 통해 불러오도록 구현해보았습니다.

여기서는 EmotionJS 라이브러리를 통해 Image Styled Component를 생성하고, 일반 이미지 태그처럼 컴포넌트 내에서 불러와 사용했습니다.

그럼 구현한 프로필 이미지 컴포넌트를 메인 페이지에서 불러와 확인해봅시다.

또, 위에서 구현한 글로벌 스타일 컴포넌트도 적용해봅시다.

index.tsx 파일을 다음과 같이 수정해주세요.

  • src/pages/index.tsx
import React, { FunctionComponent } from 'react'
import styled from '@emotion/styled'
import GlobalStyle from 'components/Common/GlobalStyle'
import ProfileImage from 'components/Main/ProfileImage'

const Container = styled.div`
  display: flex;
  flex-direction: column;
  height: 100%;
`

const IndexPage: FunctionComponent = function () {
  return (
    <Container>
      <GlobalStyle />
      <ProfileImage />
    </Container>
  )
}

export default IndexPage

여기까지 잘 따라오셨다면 흰 배경화면에 작게 원형의 프로필 이미지 사진이 보여야합니다.

프로필 이미지 사진이 보인다면, 본격적으로 Introduction.tsx 파일을 작성해봅시다.

  • src/components/Main/Introduction.tsx
import React, { FunctionComponent } from 'react'
import styled from '@emotion/styled'
import ProfileImage from 'components/Main/ProfileImage'

const Background = styled.div`
  width: 100%;
  background-image: linear-gradient(60deg, #29323c 0%, #485563 100%);
  color: #ffffff;
`

const Wrapper = styled.div`
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: flex-start;
  width: 768px;
  height: 400px;
  margin: 0 auto;
`

const SubTitle = styled.div`
  font-size: 20px;
  font-weight: 400;
`

const Title = styled.div`
  margin-top: 5px;
  font-size: 35px;
  font-weight: 700;
`

const Introduction: FunctionComponent = function () {
  return (
    <Background>
      <Wrapper>
        <ProfileImage />

        <div>
          <SubTitle>Nice to Meet You,</SubTitle>
          <Title>I'm Junior Frontend Developer Hyun.</Title>
        </div>
      </Wrapper>
    </Background>
  )
}

export default Introduction

그럼 이제 메인 페이지에 Introduction 컴포넌트를 불러와 띄워봅시다.

index.tsx 파일을 다음과 같이 수정해주세요.

  • src/pages/index.tsx
import React, { FunctionComponent } from 'react'
import styled from '@emotion/styled'
import GlobalStyle from 'components/Common/GlobalStyle'
import Introduction from 'components/Main/Introduction'

const Container = styled.div`
  display: flex;
  flex-direction: column;
  height: 100%;
`

const IndexPage: FunctionComponent = function () {
  return (
    <Container>
      <GlobalStyle />
      <Introduction />
    </Container>
  )
}

export default IndexPage

푸터 컴포넌트 구현하기

푸터 컴포넌트는 다른 페이지에서도 사용되기 때문에 Common 디렉토리에 저장하겠습니다.

Footer.tsx 파일을 생성한 후, 다음과 같이 코드를 작성해주세요.

단순히 텍스트 스타일을 적용해 띄워주는 단순한 컴포넌트이므로 코드 설명은 생략하겠습니다.

  • src/components/Common/Footer.tsx
import React, { FunctionComponent } from 'react'
import styled from '@emotion/styled'

const FooterWrapper = styled.div`
  display: grid;
  place-items: center;
  margin-top: auto;
  padding: 50px 0;
  font-size: 15px;
  text-align: center;
  line-height: 1.5;
`

const Footer: FunctionComponent = function () {
  return (
    <FooterWrapper>
      Thank You for Visiting My Blog, Have a Good Day 😆
      <br />© 2021 Developer Hyun, Powered By Gatsby.
    </FooterWrapper>
  )
}

export default Footer

푸터 컴포넌트 작성이 끝났다면, 메인 페이지에서 컴포넌트를 불러와 적용해봅시다.

  • src/pages/index.tsx
import React, { FunctionComponent } from 'react'
import styled from '@emotion/styled'
import GlobalStyle from 'components/Common/GlobalStyle'
import Footer from 'components/Common/Footer'
import Introduction from 'components/Main/Introduction'

const Container = styled.div`
  display: flex;
  flex-direction: column;
  height: 100vh;
`

const IndexPage: FunctionComponent = function () {
  return (
    <Container>
      <GlobalStyle />
      <Introduction />
      <Footer />
    </Container>
  )
}

export default IndexPage