๐ฎ Styled Components ๋ฅผ ์จ๋ณด์
Styled Components ๋ React ์ปดํฌ๋ํธ ์์คํ
์์์ ๋ณต์กํ CSS๋ฅผ ์ด๋ป๊ฒ ๊ฐ์ ํ ์ ์์์ง์ ๋ํ ๊ฒฐ๊ณผ์ด๋ค. ๋ค์๊ณผ ๊ฐ์ ์ด์ ์ด ์๋ค.
๋ ๋๋ง๋๋ ์ปดํฌ๋ํธ๋ฅผ ์ถ์ ํ์ฌ ํด๋น ์คํ์ผ๋ง ์ฝ์
ํ๊ณ ์์ ํ๋ค.
์ฝ๋๋ฅผ ๋ถํ ํ์ฌ ์ต์ํ์ ์ฝ๋๋ง ๋ก๋ํ ์ ์๋ค.
๊ณ ์ ํ ํด๋์ค ์ด๋ฆ์ ์์ฑํด์ฃผ๊ธฐ ๋๋ฌธ์ ํด๋์ค๋ช
์ ๋ฒ๊ทธ๊ฐ ์๋ค.
๋ฐ๋ผ์, ํ๋์ ์ปดํฌ๋ํธ๊ฐ ์ญ์ ๋๋ฉด, ํด๋นํ๋ ๋ชจ๋ ์คํ์ผ์ ์ญ์ ํ ์ ์๋ค.
์ปดํฌ๋ํธ์ props ์ ๊ธ๋ก๋ฒ ํ
๋ง๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์คํ์ผ์ ์กฐ์ ํ์ฌ ์ง๊ด์ ์ผ๋ก ๊ด๋ฆฌํ๋ค.
์ปดํฌ๋ํธ์ ์ํฅ์ ๋ฏธ์น๋ ์คํ์ผ์ ์ฐพ๊ธฐ ์ํด์ ์ฌ๋ฌ ํ์ผ์ ์กฐ์ฌํ์ง ์์๋ ๋๋ค.
ํ์ค์ ๋ง๊ฒ CSS๋ฅผ ์์ฑํ๊ณ ๋๋จธ์ง๋ Styled Components ๊ฐ ์ฒ๋ฆฌํ๋๋ก ํ๋ค. tailwind ์ ๊ฐ์ ๊ฒฝ์ฐ์๋ ํ์ค์ ๋ง๋ CSS๋ ์๋๊ธฐ ๋๋ฌธ์, ์ง์
์ฅ๋ฒฝ์ด ์๋ค.
๐ธ Styled Components ์ค์น
npm ์ผ๋ก ์ค์นํ๋, type ๊น์ง ์ค์นํด์ค๋ค.
npm install styled-components
npm i -D @types/styled-components @swc/plugin-styled-components
SWC๋ก Babel ์ ๋์ฒดํ๋ค.
npm i -D @swc/plugin-styled-components
React ์์ SWC๋?
Speedy Web Compiler์ ์ฝ์
Rust๋ก ์์ฑ๋ ์ด๊ณ ์ ์๋ฐ์คํฌ๋ฆฝํธ/ํ์
์คํฌ๋ฆฝํธ ์ปดํ์ผ๋ฌ
๋ฐ๋ฒจ๊ณผ ํ์
์คํฌ๋ฆฝํธ๋ฅผ ๋์ฒดํ ์ ์๋๋ก ์ค๊ณ๋์ด ํจ์ฌ ๋น ๋ฅธ ์ปดํ์ผ ์๊ฐ์ ์ ๊ณต
SWC๋ ์ปดํ์ผ๊ณผ ๋ฒ๋ค๋ง ๋ชจ๋์ ์ฌ์ฉ ๊ฐ๋ฅ
์ปดํ์ผ์ ๊ฒฝ์ฐ, ์ต์ JavaScript ๊ธฐ๋ฅ์ ์ฌ์ฉํ์ฌ JavaScript/TypeScript ํ์ผ์ ๊ฐ์ ธ์ ๋ชจ๋ ์ฃผ์ ๋ธ๋ผ์ฐ์ ์์ ์ง์๋๋ ์ ํจํ ์ฝ๋๋ฅผ ์ถ๋ ฅํ๋ค.
.swcrc ํ์ผ ์์ฑํ๊ธฐ
{
"jsc": {
"experimental": {
"plugins": [
[
"@swc/plugin-styled-components",
{
"displayName": true,
"ssr": true
}
]
]
}
}
}
VSCODE ํ์ฅ ํ๋ก๊ทธ๋จ ์ค์น(์ค์)
vscode ์์ ํธ๋ฆฌํ๊ฒ ์ฌ์ฉํ๊ธฐ ์ํด์ vscode-styled-components extension ์ ์ค์นํ๋ค.
๐ ์ฌ์ฉํด๋ณด๊ธฐ
1. ๊ธฐ๋ณธ์ ์ธ ์ฌ์ฉ๋ฐฉ๋ฒ
import styled from 'styled-components';
const Wrapper = styled.section`
padding: 4em;
background: papayawhip;
`;
const Title = styled.h1`
font-size: 1.5em;
text-align: center;
color: palevioletred;
`;
export default function Test() {
<Wrapper>
<Title className={className}>title</Title>
</Wrapper>;
}
2. ์ฌ๋ฌ๊ฐ์ง ์คํ์ผ์ ์ ์ํ ํ ๋๊ฒจ๋ฐ์ ์ฌ์ฉํ๊ธฐ
import styled from 'styled-components';
const Wrapper = styled.section`
padding: 4em;
background: papayawhip;
`;
const Title = styled.h1`
font-size: 1.5em;
text-align: center;
color: palevioletred;
`;
const BigTitle = styled(Title)`
font-size: 3em;
`;
const RedBigTitle = styled(BigTitle)`
font-size: 3em;
color: red;
`;
export default function Test() {
<Wrapper>
<RedBigTitle>title</RedBigTitle>
</Wrapper>;
}
3. return ์ฝ๋๋ฅผ ๋ฐ๋ก ๋นผ์ className ์ผ๋ก ๋์ฒดํ์ฌ ์ฌ์ฉํ๊ธฐ
import styled from 'styled-components';
const Wrapper = styled.section`
padding: 4em;
background: papayawhip;
`;
const Title = styled.h1`
font-size: 1.5em;
text-align: center;
color: palevioletred;
`;
const BigTitle = styled(Title)`
font-size: 3em;
`;
const RedBigTitle = styled(BigTitle)`
font-size: 3em;
color: red;
`;
function TitleCSS({ className }: React.HtmlHTMLAttributes<HTMLElement>) {
return (
<Wrapper>
<RedBigTitle className={className}>title</RedBigTitle>
</Wrapper>
);
}
const SmallTitle = styled(TitleCSS)`
font-size: 0.8rem;
`;
export default function Test() {
return <SmallTitle />;
}
์์๋ ๊ฒ: styled. ์ ์ญํ ์ ํด๋์ค๋ฅผ ์ถ๊ฐํ๋ ๊ฒ์ด๋ค.
3. props ๊ฐ์ ์ฌ์ฉํ์ฌ ๋์ ์ผ๋ก CSS ์์ฑ ๊ฐ์ ๋ณ๊ฒฝ
version 1
import { styled } from 'styled-components';
import { useBoolean } from 'usehooks-ts';
type ButtonProps = {
active?: boolean;
};
function background(props: ButtonProps) {
return props.active ? '#00FF' : '#FFF';
}
const Button = styled.button<ButtonProps>`
background: ${(props) => background(props)};
`;
export default function Switch() {
const { value: active, toggle } = useBoolean(false);
return (
<Button type='button' onClick={toggle} active={active}>
On/Off
</Button>
);
}
version 2
import { styled } from 'styled-components';
import { useBoolean } from 'usehooks-ts';
type ButtonProps = {
active?: boolean;
};
const Button = styled.button<ButtonProps>`
font-size: ${(props: ButtonProps) => (props.active ? '2rem' : '1rem')};
background: #fff;
`;
export default function Switch() {
const { value: active, toggle } = useBoolean(false);
return (
<Button type='button' onClick={toggle} active={active}>
On/Off
</Button>
);
}
4. attr ์ค์
import { css, styled } from 'styled-components';
import { useBoolean } from 'usehooks-ts';
type ButtonProps = {
type?: 'button' | 'submit' | 'reset';
active?: boolean;
};
const Button = styled.button.attrs<ButtonProps>((props) => ({
type: props.type ?? 'button',
}))<ButtonProps>`
background: #fff;
${(props: ButtonProps) =>
props.active &&
css`
background: red;
`}
`;
const PrimaryButton = styled(Button)`
background: black;
color: white;
${(props: ButtonProps) =>
props.active &&
css`
background: red;
`}
`;
export default function Switch() {
const { value: active, toggle } = useBoolean(false);
return (
<PrimaryButton type='submit' onClick={toggle} active={active}>
On/Off
</PrimaryButton>
);
}
Theme
jest manual mock ๋ฌธ์ ๋ณด๊ธฐ
Last updated