๐ŸœAnt Design, _App.js, PropTypes

๐ŸœAnt Design

๋ฆฌ์•กํŠธ๋ฅผ ์ง€์›ํ•˜๋Š” UI ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ์—ฌ๋Ÿฌ ๊ฐ€์ง€๊ฐ€ ์žˆ๋‹ค.

Bootstrap, Material UI, Ant Design ๋“ฑ๋“ฑ์ด ์žˆ๋Š”๋ฐ, ์ฝ”๋“œ์Šคํ…Œ์ด์ธ ์˜ ์›น ๊ฐœ๋ฐœ ๊ณผ์ •์—์„œ๋Š” ํ•ด๋‹น ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ์‚ฌ์šฉ์„ ํ•˜์ง€ ์•Š๋„๋ก ์•ˆ๋‚ดํ•ด ์คฌ๋‹ค.

์™œ๋ƒํ•˜๋ฉด CSS ์˜ ๊ตฌ์กฐ๋ฅผ ๋ฐ”๋‹ฅ ๋ถ€ํ„ฐ ํ•˜๋‚˜ ํ•˜๋‚˜ ๋งŒ๋“ค ์ค„ ์•Œ์•„์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

๊ทธ๋Ÿฐ๋ฐ ํ˜„์žฌ๋Š” ๊ณผ์ •์„ ์กธ์—…์„ ํ•œ ์ƒํƒœ์ด๊ธฐ๋„ ํ•˜๊ณ , ํ˜„์—…์— ๊ณ„์‹  ๊ฐœ๋ฐœ์ž ๋ถ„๋“ค์˜ ์ด์•ผ๊ธฐ๋ฅผ ๋“ค์–ด๋ณด๋‹ˆ ์‚ฌ์šฉ์„ ํ•ด ๋ณด์•„์•ผ ๊ฒ ๋‹ค๋Š” ์ƒ๊ฐ์ด ๋“ค์—ˆ๋‹ค.

์™œ๋ƒํ•˜๋ฉด,

antd

antd ํŽ˜์ด์ง€๋ฅผ ๋“ค์–ด๊ฐ€์„œ code ๋ถ€๋ถ„์„ ๋ˆŒ๋Ÿฌ ๋ณด๋ฉด ์œ„ ์‚ฌ์ง„๊ณผ ๊ฐ™์ด ํด๋ž˜์Šคํ˜• ์ปดํฌ๋„ŒํŠธ๋“ค์ด ๋‚˜์™€ ์žˆ๋‹ค.

๊ทธ๋ƒฅ ๋ง‰ ๊ฐ€์ ธ๋‹ค ์“ฐ๋Š” ๊ฒƒ์ด ์•„๋‹Œ, ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ๋กœ ๋ณ€๊ฒฝ๋„ ์‹œ์ผœ ๋ณด๋ฉด์„œ ๋ณด๋‹ค ๋” ๋‚˜์€ ์ฝ”๋“œ๋ฅผ ์งœ๋Š”๋ฐ ๋„์›€์ด ๋  ์ˆ˜ ์žˆ์„ ๊ฑฐ ๊ฐ™์•˜๋‹ค.

๋‹จ์ˆœํžˆ CSS ๋ฅผ ํ•˜๋Š” ์‹œ๊ฐ„์„ ์•„๋ผ๊ณ ์ž ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ, ์ด๋Ÿฌํ•œ ์ฝ”๋“œ ๊ตฌ์กฐ๋ฅผ ์ดํ•ดํ•˜๋Š” ๋ฐ ๋„์›€์„ ์ค„ ๊ฒƒ์ด๋ฏ€๋กœ ๋‚˜์ค‘์— ํ˜ผ์ž ๋ฌด์–ธ๊ฐ€๋ฅผ ๋งŒ๋“ค๊ณ  ๋ฐ”๋‹ฅ๋ถ€ํ„ฐ CSS ๊ตฌ์กฐ ๋ ˆ์ด์•„์›ƒ์„ ์งค ๋•Œ ํ•ด๋‹น ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์‚ฌ์šฉ ๊ฒฝํ—˜์ด ๋‚ด๊ฒŒ ๋„์›€์„ ์ค„ ๊ฒƒ ๊ฐ™๋‹ค๊ณ  ํŒ๋‹จํ–ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ํ˜„์—…์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์ด ์žˆ๋Š” ๋“ฏ ํ•˜๊ธฐ๋„ ํ–ˆ๋‹ค.

๐ŸœAnt Design ์˜ ๊ธฐ๋ณธ ์‚ฌ์šฉ

https://ant.design/docs/react/introduce

๊ณต์‹ ๋ฌธ์„œ๋ฅผ ์ฐธ์กฐํ•ด ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ํ˜„์žฌ ๋”ฐ๋ผ ๋ฐฐ์šฐ๋ฉด์„œ ์ง„ํ–‰ ์ค‘์ธ ์ฝ”๋“œ๋ฅผ ์˜ฎ๊ฒจ ๋ณธ๋‹ค.

import React from 'react'
import PropTypes from 'prop-types'
import Link from 'next/Link'
import { Menu } from 'antd'
// pages directory ์•ˆ์˜ ํŽ˜์ด์ง€ ๋“ค์ด ๊ณตํ†ต์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ์•ฑ ๋ ˆ์ด์•„์›ƒ์„ ๋งŒ๋“ ๋‹ค.
const AppLayout = ({ children }) => {
  return (
    <div>
      <Menu mode="horizontal">
        <Menu.Item>
          <Link href="/">
            <a>๋ฉ”์ธ</a>
          </Link>
        </Menu.Item>
        <Menu.Item>
          <Link href="/profile">
            <a>ํ”„๋กœํ•„</a>
          </Link>
        </Menu.Item>
        <Menu.Item>
          <Link href="/signup">
            <a>ํšŒ์›๊ฐ€์ž…</a>
          </Link>
        </Menu.Item>
      </Menu>
      {children}
    </div>
  )
}

AppLayout.propTypes = {
  children: PropTypes.node.isRequired,
}

export default AppLayout

pages ๋‚ด ๊ฐ๊ฐ์˜ ํŒŒ์ผ (ํŽ˜์ด์ง€) ๋“ค์ด ๊ณตํ†ต์œผ๋กœ ์‚ฌ์šฉํ•  ๋ ˆ์ด์•„์›ƒ์˜ ์ปดํฌ๋„ŒํŠธ ์ด๋‹ค.

ํ•˜์ง€๋งŒ ์ด๋ ‡๊ฒŒ๋งŒ ํ–ˆ์„ ๋•Œ๋Š” CSS ๊ฐ€ ์ „ํ˜€ ๋จนํžˆ์ง€ ์•Š๊ณ  ๋ฌด์–ธ๊ฐ€ ๊นจ์ ธ ์žˆ์Œ์„ ํ™•์ธํ•˜๊ฒŒ ๋œ๋‹ค.

๋ฌดํ„ฑ๋Œ€๊ณ  antd ๋ฅผ ๊ฐ€์ ธ๋‹ค ์“ฐ๋Š” ๊ฒƒ์ด ์•„๋‹Œ ๋ฐ”๋กœ React ์™€ ์—ฐ๊ฒฐ์„ ์ง€์–ด์•ผ ํ•œ๋‹ค.

๐Ÿœantd.css ์ž„ํฌํŠธ ํ•˜๊ธฐ

Next.js ์—๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ Webpack ์ด ๋‚ด์žฅ๋˜์–ด ์žˆ๋‹ค๊ณ  ํ•œ๋‹ค. ์ด ์›นํŒฉ์ด CSS ๋ฅผ ๋ณด๋Š” ์ˆœ๊ฐ„ ์Šคํƒ€์ผ ํƒœ๊ทธ๋กœ ๋ฐ”๊พธ์–ด ํ™•์žฅ์ž์— ์ƒ๊ด€์—†์ด ํ•ฉ์ณ html ์— ๋„ฃ์–ด์ค€๋‹ค๊ณ  ํ•œ๋‹ค.

๊ทธ๋ž˜์„œ,

import 'antd/dist/antd.css'

๋ฅผ ์ƒ์œ„์— import ํ•ด์ฃผ๋ฉด ์•Œ์•„์„œ ์›นํŒฉ์ด ์ฒ˜๋ฆฌ๋ฅผ ํ•ด์ฃผ๋Š”๋ฐ, ๊ทธ๋Ÿผ ์–ด๋””์— import ๋ฅผ ํ•ด์ค„๊นŒ?

pages ์— ์žˆ๋Š” ๊ฐ ํŒŒ์ผ๋งˆ๋‹ค ๋ชจ๋‘ ํ•ด๋‹น ์ฝ”๋“œ๋ฅผ ๋„ฃ์–ด์ฃผ์–ด์•ผ ํ• ๊นŒ? ์•„๋‹ˆ๋‹ค.

๐Ÿ pages ๋‚ด _app.js ๋ฅผ ์ƒ์„ฑ

_app.js ํŒŒ์ผ์—์„œ page ๋“ค์˜ ๊ณตํ†ต๋˜๋Š” ์‚ฌํ•ญ๋“ค์„ ์ฒ˜๋ฆฌํ•ด ์ค„ ์ˆ˜๊ฐ€ ์žˆ๋‹ค.

import React from 'react'
import 'antd/dist/antd.css'
import PropTypes from 'prop-types'

const NodeBird = ({ Component }) => {
  return <Component />
}

NodeBird.propTypes = {
  Component: PropTypes.elementType.isRequired,
}

export default NodeBird

pages ๊ฒฝ๋กœ ๋‚ด index.js, profile.js, signup.js ๋“ฑ์˜ Component ๋ถ€๋ถ„์ด props ๋กœ ์ „๋‹ฌ ๋˜์–ด์„œ ํ•ด๋‹น Component ๋ถ€๋ถ„์ด ๋ฆฌํ„ด๋˜๋Š” ์ฝ”๋“œ์ด๋‹ค.

์ฆ‰ _app.js ๊ฐ€ pages ์˜ ๋‹ค๋ฅธ ํŒŒ์ผ๋“ค์˜ โ€œ๋ถ€๋ชจโ€ ์ธ ์…ˆ์ด๋‹ค.

๋ชจ๋“  ํŽ˜์ด์ง€์—์„œ ๊ณตํ†ต์ธ ๋ถ€๋ถ„์€ _app.js ์— ๋„ฃ์œผ๋ฉด ๋œ๋‹ค >>> pages ๋“ค์˜ ๊ณตํ†ต ๋ถ€๋ถ„!

ํŠน์ • ์ปดํฌ๋„ŒํŠธ ๋ผ๋ฆฌ ๊ณตํ†ต์ธ ๋ถ€๋ถ„์€ Component ๋ฅผ ๋ณ„๋„๋กœ ๋งŒ๋“ค์–ด ๊ฐœ๋ณ„ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๊ฐ์‹ธ์ค€๋‹ค.

๐Ÿ”ฌpropTypes

https://ko.reactjs.org/docs/typechecking-with-proptypes.html

๋ฆฌ์•กํŠธ ๊ณต์‹๋ฌธ์„œ ์ฐธ์กฐ.

props ๋กœ ๋„˜์–ด์˜ค๋Š” ๊ฒƒ๋“ค์— ๋Œ€ํ•œ ์ ๊ฒ€์ด ๊ท€์ฐฎ? ์•„ ๋ณด์ผ ์ˆ˜๋„ ์žˆ์ง€๋งŒ ๊ทธ๋งŒํผ ์„œ๋น„์Šค์˜ ์•ˆ์ •์„ฑ์ด ๋†’์•„์ง€๊ณ  ๋ฒ„๊ทธ๋ฅผ ์˜ˆ๋ฐฉํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•œ๋‹ค.

โœ…Next.js ์—์„œ head ํƒœ๊ทธ๋ฅผ ์ˆ˜์ •ํ•˜๊ณ  ์‹ถ์„ ๋•Œ

Next.js ๋Š” Head ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ œ๊ณตํ•œ๋‹ค.

์ผ๋ฐ˜ ๋ฆฌ์•กํŠธ์—์„œ๋Š” public ๊ฒฝ๋กœ ๋‚ด index.html ์—์„œ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.

์•„๋ž˜ ์ฝ”๋“œ๋ฅผ ๋ณด์ž.

import React from 'react'
import 'antd/dist/antd.css'
import PropTypes from 'prop-types'
import Head from 'next/head' // Head ์ปดํฌ๋„ŒํŠธ import ํ•˜๊ธฐ

const NodeBird = ({ Component }) => {
  return (
    <>
      <Head>
        <meta charSet="utf-8" />
        <title>NodeBird</title>
      </Head>
      <Component />
    </>
  )
}

NodeBird.propTypes = {
  Component: PropTypes.elementType.isRequired,
}

export default NodeBird

ํŽ˜์ด์ง€ ๋ณ„๋กœ title ๋“ฑ์„ ๋‹ค๋ฅด๊ฒŒ ์ ์šฉํ•ด ์ฃผ๊ณ  ์‹ถ๋‹ค๋ฉด ํ•ด๋‹น ํŽ˜์ด์ง€ ๋งˆ๋‹ค Head ๋ฅผ ๋ถˆ๋Ÿฌ์™€์„œ ์ž…๋ง›์— ๋งž๊ฒŒ ์ˆ˜์ •ํ•˜๋ฉด ๋  ๊ฒƒ์ด๋‹ค.


Written by@[DotoriMook]
ํ”„๋ก ํŠธ์—”๋“œ ์ฃผ๋‹ˆ์–ด ๊ฐœ๋ฐœ์ž ๋„ํ† ๋ฆฌ๋ฌต์˜ ๊ธฐ์ˆ ๊ฐœ๋ฐœ ๋ธ”๋กœ๊ทธ ์ž…๋‹ˆ๋‹ค.

GitHubMediumTwitterFacebook