2023. 8. 14. 15:43ใStudy_Develop/React
ํจํค์ง ์ค์น
npm i @emotion/react
Emotion์ ๋ฐ๋์ React ํ๋ก์ ํธ์์๋ง ์ฌ์ฉํด์ผ ํ๋ ๊ฒ์ ์๋๋ค.
์ผ๋ฐ jsํ๋ก์ ํธ์์๋ @emotion/cssํจํค์ง๋ฅผ ์ค์นํ๋ฉด ๋๋ค.
๊ธฐ๋ณธ ๋ฌธ๋ฒ
Styled Components์ ๊ฝ์ด styled()ํจ์์๋ค๋ฉด, Emotion์ ๊ฝ์ css()ํจ์์ด๋ค.
์ค๋ ๊ธฐ๊ฐ ๋์ ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์๋ก ๊ฒฝ์ํ๋ฉด์ ํ์ฌ๋ Styled Components๋ css()ํจ์๋ฅผ ์ฌ์ฉํ ์ ์๊ณ ,
Emotion๋ ๋ค์ง์ธ๋ผ styled()ํจ์๋ฅผ ์ ๊ณตํ๊ณ ์๋ค.
ํจ์๋ css ์ ์ธ ๋ด์ฉ์ ์ธ์๋ก ๋ฐ๋๋ฐ ๊ฐ์ฒดํ์ผ๋ก ๋๊ฒจ๋ ๋๊ณ , ๋ฌธ์ํ์ผ๋ก ๋๊ฒจ๋ ๋๋ค.
๊ทธ๋ฆฌ๊ณ css() ํจ์์ ๋ฐํ ๊ฒฐ๊ณผ๋ฅผ ํด๋น ์คํ์ผ์ ์ ์ฉํ๊ณ ์ถ์ HTML ์์๋ React ์ปดํฌ๋ํธ์ css๋ผ๋ prop์ ๋๊ฒจ์ฃผ๋ฉด ๋๋ค.
- ๊ฐ์ฒดํ ์คํ์ผ
/** @jsxImportSource @emotion/react */
import { css } from "@emotion/react";
function MyComponent() {
return (
<div
css={css({
backgroundColor: "yellow",
})}
>
๋
ธ๋์ ์์ญ
</div>
);
}
- ๋ฌธ์ํ ์คํ์ผ
/** @jsxImportSource @emotion/react */
import { css } from "@emotion/react";
function MyComponent() {
return (
<div
css={css`
background-color: yellow;
`}
>
๋
ธ๋์ ์์ญ
</div>
);
}
Emotion ๋ฌธ์์์๋ ๊ฐ๊ธ์ ์คํ์ผ์ ๊ฐ์ฒด๋ก ์ ์ธํด์ css() ํจ์์ ๋๊ธฐ๋ผ๊ณ ๊ถ์ฅํ๊ณ ์๋๋ฐ์. ์ด ๋ฐฉ๋ฒ์ ์ฌ์ฉํ๋ฉด css() ํจ์๋ฅผ ํธ์ถ์ ์๋ตํ๊ณ css prop์ ๋ฐ๋ก ๊ฐ์ฒด๋ฅผ ๋๊ธธ ์ ์์ผ๋ฉฐ, ํนํ ํ์ ์คํฌ๋ฆฝํธ(TypeScript)๋ฅผ ์ฌ์ฉํ๋ฉด ํ์ ์ฒดํน(type checking)์ ํตํด ๋ฒ๊ทธ๋ ์ค์ผ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค.
๊ณ ์ ์คํ์ผ๋ง
<button> ์์์ css prop์ ํตํด์ ๋ค์ํ css ์์ฑ ์ ์๋ฅผ ๊ฐ์ฒด๋ก ๋๊ฒจ๋ณด๊ธฐ
/** @jsxImportSource @emotion/react */
function Button({ children }) {
return (
<button
css={{
borderRadius: "6px",
border: "1px solid rgba(27, 31, 36, 0.15)",
backgroundColor: "rgb(246, 248, 250)",
color: "rgb(36, 41, 47)",
fontFamily: "-apple-system, BlinkMacSystemFont, sans-serif",
fontWeight: "600",
lineHeight: "20px",
fontSize: "14px",
padding: "5px 16px",
textAlign: "center",
cursor: "pointer",
appearance: "none",
userSelect: "none",
}}
>
{children}
</button>
);
}
export default Button;
์ด ์ฝ๋๋ฅผ ๋ค๋ฅธ React์ปดํฌ๋ํธ์์ ์ฌ์ฉํ๋ ค๋ฉด?
import { Button } from "./Button";
function App() {
return <Button>Button</Button>;
}
๊ทธ๋ ๋ค๋ฉด , ๋ธ๋ผ์ฐ์ ์์ ์์ค๋ณด๊ธฐ๋ฅผ ํด๋ณด๋ฉด button์์์ Emotion ์ด ์๋์ผ๋ก ์์ฑํด์ค ํด๋์ค ์ด๋ฆ์ด ๋ถ์ด์๋ค๋ ๊ฒ์ ํ์ธ ํ ์ ์๋ค.
๊ฐ๋ณ ์คํ์ผ๋ง(props ์ ์ก)
Emotion์ ์ฌ์ฉํ๋ฉด React ์ปดํฌ๋ํธ์ ๋์ด์จ props์ ๋ฐ๋ผ ๋ค๋ฅธ ์คํ์ผ์ ์ฝ๊ฒ ์ ์ฉํ ์ ์๋ค. ๋ฐ๊พธ๊ณ ์ถ์ CSS ์์ฑ๊ฐ์ ์์ ๋์ ์ prop์ ๋ฐ๋ผ ๋ณํ๋ ๋ณ์๋ฅผ ํ ๋นํด์ฃผ๊ธฐ๋ง ํ๋ฉด ๋๋ค.
์๋ฅผ ๋ค์ด, <Button/> ์ปดํฌ๋ํธ์ variant๋ผ๋ prop์ ์ถ๊ฐํ ํ์, ์ด prop์ ์ด๋ค ๊ฐ์ด ๋์ด์ค๋๋์ ๋ฐ๋ผ ๊ธ์์์ด ๋ฐ๋๋๋ก ์ฝ๋๋ฅผ ์ง๋ณด์๋ค.
/** @jsxImportSource @emotion/react */
const colors = {
default: "rgb(36, 41, 47)",
danger: "rgb(207, 34, 46)",
outline: "rgb(9, 105, 218)",
};
function Button({ children, variant = "default" }) {
return (
<button
css={{
borderRadius: "6px",
border: "1px solid rgba(27, 31, 36, 0.15)",
backgroundColor: "rgb(246, 248, 250)",
color: colors[variant],
fontFamily: "-apple-system, BlinkMacSystemFont, sans-serif",
fontWeight: "600",
lineHeight: "20px",
fontSize: "14px",
padding: "5px 16px",
textAlign: "center",
cursor: "pointer",
appearance: "none",
userSelect: "none",
}}
>
{children}
</button>
);
}
export default Button;
import Button from "./Button";
function App() {
return (
<>
<Button variant="default">Default</Button>
<Button variant="danger">Danger</Button>
<Button variant="outline">Outline</Button>
</>
);
}
์ด์ ๊ฐ์ ๋ฐฉ์์ผ๋ก button์ color๋ฅผ props์ ๋ฌ๋ก ์๋ง ๋ณ๊ฒฝ๊ฐ๋ฅํ๊ฒ ์ฝ๋๋ฅผ ์งค ์ ์๋ค.
๊ฐ๋ณ ์คํ์ผ๋ง 2 (prop๋ฅผ ์ฌ๋ฌ๊ฐ ์ ๋ฌ)
size๋ผ๋ prop์ ๋์ด์จ ๊ฐ์๋ฐ๋ผ์ ๋ฒํผ์ ํฌ๊ธฐ๊ฐ ๋ฐ๋๋๋ก ํด๋ณด์.
fontSize์์ฑ๊ณผ padding์์ฑ์ ๋ค๋ฅด๊ฒ ํด๋ณด๊ฒ ๋ค.
/** @jsxImportSource @emotion/react */
const colors = {
default: "rgb(36, 41, 47)",
danger: "rgb(207, 34, 46)",
outline: "rgb(9, 105, 218)",
};
const sizeStyles = {
sm: {
fontSize: "12px",
padding: "3px 12px",
},
md: {
fontSize: "14px",
padding: "5px 16px",
},
lg: {
fontSize: "16px",
padding: "9px 20px",
},
};
function Button({ children, size = "md", variant = "default" }) {
return (
<button
css={{
borderRadius: "6px",
border: "1px solid rgba(27, 31, 36, 0.15)",
backgroundColor: "rgb(246, 248, 250)",
color: colors[variant],
fontFamily: "-apple-system, BlinkMacSystemFont, sans-serif",
fontWeight: "600",
lineHeight: "20px",
...sizeStyles[size],
textAlign: "center",
cursor: "pointer",
appearance: "none",
userSelect: "none",
}}
>
{children}
</button>
);
}
export default Button;
import Button from "./Button";
function App() {
return (
<>
<Button size="sm" variant="default">
Default
</Button>
<Button size="md" variant="default">
Default
</Button>
<Button size="lg" variant="default">
Default
</Button>
<hr />
<Button size="sm" variant="danger">
Danger
</Button>
<Button size="md" variant="danger">
Danger
</Button>
<Button size="lg" variant="danger">
Danger
</Button>
<hr />
<Button size="sm" variant="outline">
Outline
</Button>
<Button size="md" variant="outline">
Outline
</Button>
<Button size="lg" variant="outline">
Outline
</Button>
</>
);
}
3๊ฐ์ง ํฌ๊ธฐ์ 3๊ฐ์ง ์์, ์ด 9๊ฐ์ง ์ข ๋ฅ์ ๋ฒํผ์ ๋ง๋ค์ด ๋ผ ์ ์๋ค.
'Study_Develop > React' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
lazy, suspense ๋ก ๋ ๋๋ง ์ฑ๋ฅ ๊ฐ์ ํ๊ธฐ (0) | 2025.06.03 |
---|---|
JSX๋? (1) | 2023.08.14 |
React ์ปดํฌ๋ํธ css ์คํ์ผ๋ง ๊ธฐ๋ณธ / Style Components(prop๋ก ํ์ฅ, as, ์์ฑ ์ถ๊ฐ, ์ ๋๋ฉ์ด์ , ๊ฐ์ ์ ํ์) (1) | 2023.08.13 |
์ฝ๋ ์คํ๋ฆฌํ ์ฌ์ฉํ๊ธฐ (0) | 2023.08.12 |
react-router๋ฅผ ํตํ ๋ฆฌ์กํธ ์ฑ๊ธํ์ด์ง ๋ง๋ค๊ธฐ / ํด๋ ๊ตฌ์กฐ (1) | 2023.08.12 |