Style
Ant-design / Styled-components
์ค์น
๋จผ์ ํจํค์ง๋ฅผ ์ค์นํด ์ค๋๋ค.
@ant-design/icons ๋ฅผ ๋ฐ๋ก ์ค์นํด์ค์ผ ํ๋ ์ด์ ๋ ๋ณดํต icon๊ณผ ๊ฐ์ ์ด๋ฏธ์ง ํจํค์ง์ ํฌ๊ธฐ๊ฐ ํฌ๊ธฐ ๋๋ฌธ์ ๋๋ค.
yarn add antd styled-component @ant-design/icons
"dependencies": {
"@ant-design/icons": "^4.2.1",
"antd": "^4.5.1",
"next": "^9.5.0",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"styled-components": "^5.1.1"
},
Ant-design์ด๋ Bootstrap์ ๋ณดํต ์ค๋ฌด์์๋ ๊ด๋ฆฌ์ํ์ด์ง์ ๊ฐ์ด ๋์์ธ์ ์ค์์ฑ์ด ์กฐ๊ธ์ ๋จ์ด์ง๋ ํ์ด์ง์ ์ฌ์ฉ๋ฉ๋๋ค.
์ ํ์ด์ง์์ ์ปดํฌ๋ํธ ๋ชฉ๋ก์ ํ์ธํ ์ ์์ต๋๋ค.
์ ์ฉ์ํค๊ธฐ
Menu component๋ฅผ ๊ฐ์ ธ์ค๊ฒ ๋๋ค๋ฉด
import React from "react";
import Link from "next/Link"; //importํด์ฃผ๊ธฐ
import { Menu } from "antd";
export default function AppLayout({ children }) {
return (
<>
<Menu mode="horizontal">
<Menu.Item>
<Link href="/">
<a>Conrad</a>
</Link>
</Menu.Item>
<Menu.Item>
<Link href="/profile">
{/* Linkํ๊ทธ ์์์ href ํด์ค๋ค ๋ด๋ถ์ aํ๊ทธ */}
<a>ํ๋กํ</a>
</Link>
</Menu.Item>
<Menu.Item>
<Link href="/signup">
<a>ํ์๊ฐ์
</a>
</Link>
</Menu.Item>
</Menu>
{children}
</>
);
}
์ด๋ ๊ฒ ์์ ํ๋ฉด ๋์ง๋ง

next๋ ์์ webPack์ด ๋ด์ฅ๋์ด์๋๋ฐ, css๋ฅผ ๋ณด๋์๊ฐ js์ ๋ฃ์ด์ฃผ๊ฒ๋ฉ๋๋ค..
pages์ ๊ณตํต์ผ๋ก ์ ์ฉํ ๊ฒ์ด์ด ์์๋๋, ๋ชจ๋ page์์ ์ผ์ผ์ด ์จ์ฃผ๋ ๊ฒ์ด ์๋๋ผ
pagesํด๋ ์์ _app.js๋ฅผ ๋ง๋ค์ด ๊ณตํต์ ์ธ ์์๋ฅผ ํ๋๋ก ์ฒ๋ฆฌํด์ฃผ๋ฉด ๋ฉ๋๋ค.
import React from "react";
import "antd/dist/antd.css";
export default function App({ Component }) {
return <Component />;
}
์ด๋ ๊ฒ ๋๋ฉด _app.js๋ ๋ค๋ฅธ ํ์ด์ง๋ค์ ๋ถ๋ชจ์์๊ฐ ๋ฉ๋๋ค. (HOC๊ฐ ๋๋๊ฒ์ด์ฃ )
Component๋ ๋ค๋ฅธ ์์๋ค ์ฆ ์ถ๋ ฅํ ํ์ด์ง๋ฅผ ์๋ฏธํ๊ฒ ๋ฉ๋๋ค.
์ด๋ฟ์๋๋ผ ๋ชจ๋ ํ์ด์ง์ ๊ณตํต๋๋ ๊ฒ๋ค์ ์ ์ด์ฃผ๋ฉด ๋๋ต๋๋ค.
head์์ญ ์ค์ ํ๊ธฐ
next๋ HTML์ headํ๊ทธ๋ฅผ ์ง์ํฉ๋๋ค.
๋ํ ์๋์ ๊ฐ์ด HTML์ title์ด๋ meta๋ ์ง์ ํด ์ค ์ ์์ต๋๋ค.
import React from "react";
import Head from "next/head";
import "antd/dist/antd.css";
export default function _app({ Component }) {
return (
<div>
<Head>
<meta charSet="utf-8"></meta>
<title>Wongeun</title>
</Head>
<Component />
</div>
);
}
๋ง์ฝ ๊ณตํต๋์ง ์๋ Head๋ผ๋ฉด index.js์ ๋ฃ์ด์ฃผ์๋ฉด ๋ฉ๋๋ค.
CSS์์ ํ๊ธฐ
์๋์ ๊ฐ์ด ๊ฒ์์ฐฝ์ ๋ฃ์ด์ฃผ์ธ์ฌ
<>
<Menu mode="horizontal">
<Menu.Item>
<Link href="/">
<a>Home</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.Item>
<Input.Search enterButton></Input.Search>
</Menu.Item>
</Menu>
{children}
</>

<Input.Search
enterButton
style={{ verticalAlign: "middle" }}
></Input.Search>
์ด๋ ๊ฒ css๋ฅผ ์ค ์๋ ์์ต๋๋ค.

๋ฐ์ํ
์ด๋ฐ CSS์์คํ ์ Grid ์์คํ ์ ๊ฐ์ง๊ณ ์๋๋ฐ
๋ชจ๋ฐ์ผํ์ด์ง๋ฅผ ๋ง๋๋ ๋ฐฉ๋ฒ์๋ ๋๊ฐ์ง๊ฐ ์์ต๋๋ค.
Ant-Design์์๋ ๋ฐ์ํ Grid์์คํ ์ ์ ๊ณตํฉ๋๋ค.
row / column ๋๊ฐ์ง ์ปดํฌ๋ํธ๋ฅผ ์ง์ํ๊ธฐ ๋๋ฌธ์ ์ฝ๊ฒ ์ ์ฉ์ํฌ ์ ์์ต๋๋ค.
์์ํ๋ฉด -> ํฐํ๋ฉด ์์ผ๋ก ๋์์ธํ๋ ๊ฒ์ด ํธํ๋ฉฐ,
์ด 24์นธ์ผ๋ก ๋๋์ด์ ธ ์๊ธฐ ๋๋ฌธ์ 24๋ก ๋๋์ด์ ธ์ผ๋ง ํ๋ฉฐ 24๊ฐ ๋์ด๊ฐ๋ฉด ์๋ฉ๋๋ค.
<Row gutter={8}> //column๋ค ๊ฐ๊ฒฉ 8px (4px+4px)
<Col xs={24} md={6}>
์ผ์ชฝ๋ฉ๋ด
</Col>
<Col xs={24} md={12}>
{children}
</Col>
<Col xs={24} md={6}>
์ค๋ฅธ์ชฝ๋ฉ๋ด
</Col>
</Row>
//๋ชจ๋ฐ์ผ์์๋ 24 24 24
//md
๋ณดํต ํ๋ธ๋ฆฟ : sm ๋ชจ๋ฐ์ผ: xs ์ด๋ ๊ฒ ์ฌ์ฉํฉ๋๋ค.
xs
screen < 576px
number | object
-
sm
screen โฅ 576px
number | object
-
md
screen โฅ 768px
number | object
-
lg
screen โฅ 992px
number | object
-
xl
screen โฅ 1200px
number | object
-
xxl
screen โฅ 1600px
number | object
-
๋ฌผ๋ก ๋์ค์ ์ปค์คํ ํ ์๋ ์์ต๋๋ค.
gutter๋ grid-gap ๊ณผ ๊ฐ์ ์์ฑ์ ๋๋ค.
์์ดํ ์ฌ์ด์ ๊ฐ๊ฒฉ์ ์๋ฏธํฉ๋๋ค.
</Col>
<Col xs={24} md={6}>
<a
href="https://ant.design/components/grid/"
target="_blank"
rel="noreferrer noopener"
>
made by Conrad
</a>
</Col>
aํ๊ทธ์์ target="_blank"
๋ฅผ ์ด์ฉํด ์์ฐฝ์ผ๋ก ๋งํฌ๋ฅผ ๋์ด๋ค๋ฉด
rel="noreferrer noopener"
์์ฑ์ ์ถ๊ฐํด ๋ณด์์ทจ์ฝ์ ์ ๋ณด์ํด์ผ๋ง ํฉ๋๋ค.
๋ก๊ทธ์ธ์ฐฝ(์ผ์ชฝ๋ฉ๋ด)๋ ๋๋ง
์ผ์ชฝ๋ฉ๋ด์๋ ๋ก๊ทธ์ธ๊ธฐ๋ฅ์ ๋ง๋ค์ด ์ค๋๋ค.
๋ฐฑ์ค๋ ์๋ฒ๊ฐ ์๊ธฐ๋๋ฌธ์ useState
๋ฅผ ์ด์ฉํ ์ํ๊ด๋ฆฌ๋ก ๋๋ฏธ๋ฐ์ดํฐ๋ฅผ ๋ง๋ค์ด ์ค๋๋ค.
const [isloggedIn, setIsLoggedIn] = useStatee(false);
์ฐ์ UserProfile.js / LoginForm.js ๋๊ฐ์ง ์ปดํฌ๋ํธ๋ฅผ ๋ง๋ค์ด์ฃผ์ธ์
Presenter๊ณผ Container๋ฅผ ๋๋ ์ ๊ด๋ฆฌํ๋ ๊ฒ์ ์์ ๋ถํฐ ๋ง์ด ์งํํ์ง๋ง,
๋ฆฌ์กํธํ์ด Hooks ์ดํ๋ก ๋๋๋๊ฑธ ์ถ์ฒํ์ง ์๋๋ค ํ์๊ธฐ์ ํ ํ์ผ์์ ์งํํด๋ด ๋๋ค.
<Form>
<div>
<label htmlFor="user-id">์์ด๋</label>
<br />
<Input name="user-id" required />
</div>
<div>
<label htmlFor="user-password">๋น๋ฐ๋ฒํธ</label>
<br />
<Input
name="user-password"
type="password"
required
/>
</div>
<div>
<Button type="primary" htmlType="submit" >
๋ก๊ทธ์ธ
</Button>
<Link href="/signup"> //ํ์๊ฐ์
ํ์ด์ง๋ก ๋์ด๊ฐ๊ธฐ
<a>
<Button>ํ์๊ฐ์
</Button>
</a>
</Link>
</div>
</Form>
useState๋ฅผ ์ด์ฉํ Input ์ํ๊ด๋ฆฌ
const [id, setId] = useState("");
const [password, setPassword] = useState("");
const onChangeId = useCallback((e) => {
setId(e.target.value);
}, []);
const onChangePassword = useCallback((e) => {
setPassword(e.target.value);
}, []);
์ด์ ์ํ๋ค์ JSX์ ์ ์ฉ์์ผ์ฃผ์ธ์
import React, { useState, useCallback } from "react";
import { Form, Input, Button } from "antd";
import Link from "next/link";
export default function LoginForm() {
const [id, setId] = useState("");
const [password, setPassword] = useState("");
const onChangeId = useCallback((e) => {
setId(e.target.value);
}, []);
const onChangePassword = useCallback((e) => {
setPassword(e.target.value);
}, []);
return (
<Form>
<div>
<label htmlFor="user-id">์์ด๋</label>
<br />
<Input name="user-id" value={id} onChange={onChangeId} required />
</div>
<div>
<label htmlFor="user-password">๋น๋ฐ๋ฒํธ</label>
<br />
<Input
name="user-password"
type="password"
value={password}
onChange={onChangePassword}
required
/>
</div>
<div style={{marginTop:10}}>
<Button type="primary" htmlType="submit" loading={false}>
๋ก๊ทธ์ธ
</Button>
<Link href="/signup">
<a>
<Button>ํ์๊ฐ์
</Button>
</a>
</Link>
</div>
</Form>
);
}
AppLayout ์ปดํฌ๋ํธ์์ ์ปดํฌ๋ํธ๋ฅผ ๋ ๋๋ง ํด์ฃผ์ธ์.

ํ๊ฐ์ง ์ฃผ์ํด์ผ ํ ์ ์ด ์์ต๋๋ค. ์์์ ์์ฑํ ์ฝ๋์ค ์๋ ์ฝ๋๋ฅผ ๋ด์ฃผ์ธ์
<div style={{marginTop:10}}>
๋ณดํต css์ ์คํ์ผ์ ์ฃผ๊ธฐ ์ํ ๋ชฉ์ ์ผ๋ก ๊ฐ๋จํ ์์ฃผ ์ฌ์ฉ๋๋ ๋ฐฉ๋ฒ์ธ๋ฐ, ์ด๋ ํฐ ๋ด์ ์ ๊ฐ์ง๊ณ ์์ต๋๋ค.
์คํ์ผ์ ์์ฒ๋ผ ๊ฐ์ฒด๋ก ์ฃผ๊ฒ๋๋ฉด ๊ฐ์ฒด์ด๊ธฐ ๋๋ฌธ์ ๋ฐ๋๊ฐ์ด ์๋ฌด๊ฒ๋ ์์ด๋ ๋ฆฌ๋ ๋๋ง ๋์ด๋ฒ๋ฆฝ๋๋ค.
์ div ํ๊ทธ๋ฅผ styled-components๋ฅผ ์ด์ฉํด ๋ฐ๊ฟ์ฃผ๊ฒ ์ต๋๋ค.
const ButtonWrapper = styled.div`
margin-top: 10px;
`;
<ButtonWrapper>
์ฌ์ค ์ฑ๋ฅ์ ํฐ ์ง์ฅ์ ์ฃผ์ง๋ ์๊ธฐ๋๋ฌธ์ ๊ฐ๋จํ ์์ ์ด๋ฉด ์ธ๋ผ์ธ์คํ์ผ์ ์ฌ์ฉํ์ ๋ ํฌ๊ฒ ๋ฌธ์ ๋ ๊ฒ์ ์์ต๋๋ค.
๋ฆฌ๋๋๋ง
์ฌ์ค ๋ฆฌ๋๋๋ง์ด ๋๋ฉด ์ฒ์๋ถํฐ ๋๊น์ง ๋ค์ ์์๋๋ ๊ฒ์ ๋ง์ต๋๋ค.
useCallBack, useMemo๋ฅผ ์ฌ์ฉํด ์บ์ฑํ๊ฒ๋๋ฉด ๊ทธ๊ฑธ ๋ง์์ค ์ ์์ฃ .
React์์๋ JSX์์ ๋ฐ๋๋ถ๋ถ๋ง ๋ค์ ๋ ๋๋งํด์ค๋๋ค.
์ฆ ์ด์ ์ ์ปดํฌ๋ํธ์ ๋น๊ตํด์ ๋ฐ๋ ๋ถ๋ถ๋ง ๋ค์ ๊ทธ๋ ค์ค๋๋ค.
Virtual DOM ์ฆ, ํจ์ํ ์ปดํฌ๋ํธ ์์ return๋๋ ๋ถ๋ถ์ ๋ฆฌ์กํธ์์๋ ์ฒ์์ ํ๋ฒ ์น ๊ทธ๋ ค์ค๋ค,
์ด์ ์ปดํฌ๋ํธ์ ๋ค์ ์ปดํฌ๋ํธ๋ฅผ ๋น๊ตํด ๋ฐ๋๊ฒ ์์ผ๋ฉด React๋ ์ปดํฌ๋ํธ๋ฅผ ๋ฆฌ๋๋๋ง ํด์ค๋๋ค.
๊ฒฐ๊ตญ ๋ฆฌ๋๋๋ง์ ์ ๊ฒํ๋ฉด ์ฑ๋ฅ์ ์ผ๋ก ์ข๊ฒ ์ฃ ?
Last updated
Was this helpful?