April 07, 2021
๋ฆฌ์กํธ๋ฅผ ์ง์ํ๋ UI ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ์ฌ๋ฌ ๊ฐ์ง๊ฐ ์๋ค.
Bootstrap, Material UI, Ant Design ๋ฑ๋ฑ์ด ์๋๋ฐ, ์ฝ๋์คํ ์ด์ธ ์ ์น ๊ฐ๋ฐ ๊ณผ์ ์์๋ ํด๋น ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์ฌ์ฉ์ ํ์ง ์๋๋ก ์๋ดํด ์คฌ๋ค.
์๋ํ๋ฉด CSS ์ ๊ตฌ์กฐ๋ฅผ ๋ฐ๋ฅ ๋ถํฐ ํ๋ ํ๋ ๋ง๋ค ์ค ์์์ผ ํ๊ธฐ ๋๋ฌธ์ด๋ค.
๊ทธ๋ฐ๋ฐ ํ์ฌ๋ ๊ณผ์ ์ ์กธ์ ์ ํ ์ํ์ด๊ธฐ๋ ํ๊ณ , ํ์ ์ ๊ณ์ ๊ฐ๋ฐ์ ๋ถ๋ค์ ์ด์ผ๊ธฐ๋ฅผ ๋ค์ด๋ณด๋ ์ฌ์ฉ์ ํด ๋ณด์์ผ ๊ฒ ๋ค๋ ์๊ฐ์ด ๋ค์๋ค.
์๋ํ๋ฉด,
antd ํ์ด์ง๋ฅผ ๋ค์ด๊ฐ์ code ๋ถ๋ถ์ ๋๋ฌ ๋ณด๋ฉด ์ ์ฌ์ง๊ณผ ๊ฐ์ด ํด๋์คํ ์ปดํฌ๋ํธ๋ค์ด ๋์ ์๋ค.
๊ทธ๋ฅ ๋ง ๊ฐ์ ธ๋ค ์ฐ๋ ๊ฒ์ด ์๋, ํจ์ํ ์ปดํฌ๋ํธ๋ก ๋ณ๊ฒฝ๋ ์์ผ ๋ณด๋ฉด์ ๋ณด๋ค ๋ ๋์ ์ฝ๋๋ฅผ ์ง๋๋ฐ ๋์์ด ๋ ์ ์์ ๊ฑฐ ๊ฐ์๋ค.
๋จ์ํ CSS ๋ฅผ ํ๋ ์๊ฐ์ ์๋ผ๊ณ ์ ํ๋ ๊ฒ์ด ์๋๋ผ, ์ด๋ฌํ ์ฝ๋ ๊ตฌ์กฐ๋ฅผ ์ดํดํ๋ ๋ฐ ๋์์ ์ค ๊ฒ์ด๋ฏ๋ก ๋์ค์ ํผ์ ๋ฌด์ธ๊ฐ๋ฅผ ๋ง๋ค๊ณ ๋ฐ๋ฅ๋ถํฐ CSS ๊ตฌ์กฐ ๋ ์ด์์์ ์งค ๋ ํด๋น ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ฌ์ฉ ๊ฒฝํ์ด ๋ด๊ฒ ๋์์ ์ค ๊ฒ ๊ฐ๋ค๊ณ ํ๋จํ๋ค.
๊ทธ๋ฆฌ๊ณ ํ์ ์์ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ๊ฐ ๋ง์ด ์๋ ๋ฏ ํ๊ธฐ๋ ํ๋ค.
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 ์ ์ฐ๊ฒฐ์ ์ง์ด์ผ ํ๋ค.
Next.js ์๋ ๊ธฐ๋ณธ์ ์ผ๋ก Webpack ์ด ๋ด์ฅ๋์ด ์๋ค๊ณ ํ๋ค. ์ด ์นํฉ์ด CSS ๋ฅผ ๋ณด๋ ์๊ฐ ์คํ์ผ ํ๊ทธ๋ก ๋ฐ๊พธ์ด ํ์ฅ์์ ์๊ด์์ด ํฉ์ณ html ์ ๋ฃ์ด์ค๋ค๊ณ ํ๋ค.
๊ทธ๋์,
import 'antd/dist/antd.css'
๋ฅผ ์์์ import ํด์ฃผ๋ฉด ์์์ ์นํฉ์ด ์ฒ๋ฆฌ๋ฅผ ํด์ฃผ๋๋ฐ, ๊ทธ๋ผ ์ด๋์ import ๋ฅผ ํด์ค๊น?
pages ์ ์๋ ๊ฐ ํ์ผ๋ง๋ค ๋ชจ๋ ํด๋น ์ฝ๋๋ฅผ ๋ฃ์ด์ฃผ์ด์ผ ํ ๊น? ์๋๋ค.
_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 ๋ฅผ ๋ณ๋๋ก ๋ง๋ค์ด ๊ฐ๋ณ ์ปดํฌ๋ํธ๋ฅผ ๊ฐ์ธ์ค๋ค.
https://ko.reactjs.org/docs/typechecking-with-proptypes.html
๋ฆฌ์กํธ ๊ณต์๋ฌธ์ ์ฐธ์กฐ.
props ๋ก ๋์ด์ค๋ ๊ฒ๋ค์ ๋ํ ์ ๊ฒ์ด ๊ท์ฐฎ? ์ ๋ณด์ผ ์๋ ์์ง๋ง ๊ทธ๋งํผ ์๋น์ค์ ์์ ์ฑ์ด ๋์์ง๊ณ ๋ฒ๊ทธ๋ฅผ ์๋ฐฉํ ์ ์๋ค๊ณ ์๊ฐํ๋ค.
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 ๋ฅผ ๋ถ๋ฌ์์ ์ ๋ง์ ๋ง๊ฒ ์์ ํ๋ฉด ๋ ๊ฒ์ด๋ค.