#2.1 styled components
creact-react-app, styled component 설치 및 셋팅
npx create-react-app react-challenge
기존 css로 작성한 것과 style component로 작성한 코드의 차이 경험
styled-component는 각각 컴포넌트로 만들어서 사용함
코드가 간결하고 재활용에 용이, 가독성 좋음
` ` 백틱 사용
#2.2 Adapting and Extending
중복되는 값을 제거하고 컴포넌트를 설정 변경 가능한 형태로 만들기
컴포넌트 확장
// 변경 전
const BoxOne = styled.div`
background-color: teal;
width: 100px;
height: 100px;
`;
const BoxTwo = styled.div`
background-color: tomato;
width: 100px;
height: 100px;
`;
// props를 이용해 컴포넌트의 설정을 변경할 수 있게
const Box = styled.div`
background-color: ${(props) => props.bgColor};
width: 100px;
height: 100px;
`;
function App() {
return (
<Father>
<Box bgColor="teal"></Box>
<Box bgColor="tomato"></Box>
</Father>
);
}
// 확장
// Circle에 Box의 property를 코드 중복 없이 가져옴
// Box의 모든 property를 가져온 후 Circle의 property 추가
const Box = styled.div`
background-color: ${(props) => props.bgColor};
width: 100px;
height: 100px;
`;
const Circle = styled(Box)`
border-radius: 50px;
`;
function App() {
return (
<Father>
<Box bgColor="teal"></Box>
{/* Circle에서도 bgColor 변경 가능 */}
<Circle bgColor="tomato"></Circle>
</Father>
);
}
컴포넌트 확장의 의미는 다른 컴포넌트의 속성을 그대로 가져와 자신의 속성을 추가하는 것
이 때, 코드 중복 발생 x
App()에서 설정한 prop의 이름과 컴포넌트에서 사용하는 props의 이름은 같아야 함
#2.3 'As' and Attrs
다수의 컴포넌트를 다룰 때 도움이 될만한 트릭들
1. 'as'
컴포넌트의 태그를 바꾸고 싶은데 스타일은 바꾸고 싶지 않을 때
뭔가를 추가할 계획이 없어서 컴포넌트를 확장하고 싶지 않을 때
ex) button 태그를 사용했으나 a 태그처럼 사용하고 싶을 때 ----> 'as'
// element에서도 <a>로 바뀜
// button -> a
const Btn = styled.button`
color: white;
background-color: tomato;
border: 0;
border-radius: 15px;
`;
function App() {
return (
<Father>
<Btn>Log in</Btn>
{/* as="a" 사용*/}
<Btn as="a" href="/">
Log in
</Btn>
</Father>
);
}
// div -> header
function App() {
return (
<Father as="header">
<Btn>Log in</Btn>
<Btn as="a" href="/">
Log in
</Btn>
</Father>
);
}
2. '.attrs'
styled components가 컴포넌트를 생성할 때, 속성값을 설정할 수 있게 해줌
tagName.attrs({})에는 해당 태그의 모든 속성을 가진 오브젝트를 담을 수 있음
만약 form이 있고 input이 많으면 하나하나 required라고 적어줘야함
const Input = styled.input.attrs({ required: true, minLength: 10 })`
background-color: tomato;
`;
function App() {
return (
<Father as="header">
<Input />
<Input />
<Input />
<Input />
<Input />
</Father>
);
}
#2.4 Animations and Pseudo Selectors
> Animations
styled component 에서의 animation
helper function을 import해서 사용
import styled, { keyframes } from "styled-components";
Box 밖에서 animation 컴포넌트 생성
기존 css와 비슷하지만 javascript의 string interpolation을 사용함
const rotationAnimation = keyframes`
/* from{}to{} */
0% {
transform:rotate(0deg);
border-radius: 0px;
}
50% {
border-radius: 100px;
}
100%{
transform:rotate(360deg);
border-radius: 0px;
}
`;
const Box = styled.div`
height: 200px;
width: 200px;
background-color: tomato;
animation: ${rotationAnimation} 1s linear infinite;
`;
function App() {
return (
<Wrapper>
<Box></Box>
</Wrapper>
);
}
> Pseudo Selectors
component에서 사용할 수 있는 selector
꼭 모든 component에 styled component 처리를 해 줄 필요는 없고 아래와 같은 방법을 사용해도 됨
Box 안에 있는 span 속 이모지를 선택
const Box = styled.div`
height: 200px;
width: 200px;
background-color: tomato;
display: flex;
justify-content: center;
align-items: center;
animation: ${rotationAnimation} 1s linear infinite;
/* Box 안에 있는 span 속 이모지를 선택 */
span {
font-size: 36px;
&:hover {
font-size: 60px;
}
&:active {
opacity: 0;
}
}
`;
function App() {
return (
<Wrapper>
<Box>
<span>🎅</span>
</Box>
</Wrapper>
);
}
#2.5 Pseudo Selectors
styled component 안의 element를 선택하는 다른 방법
tag name에 의존하고 있다면 태그명을 바꿨을 경우(span->p) 효과가 적용되지 않음
태그명에 의존하고 싶지 않다면?
-> 우리만의 styled component를 만들면 됨
Box 컴포넌트 안에 Emoji 컴포넌트를 직접적으로 타겟팅
-> 이러면 Emoji가 div든 span이든 p든 상관 없음
const Emoji = styled.span`
font-size: 36px;
`;
const Box = styled.div`
height: 200px;
width: 200px;
background-color: tomato;
display: flex;
justify-content: center;
align-items: center;
animation: ${rotationAnimation} 1s linear infinite;
${Emoji} {
&:hover {
font-size: 60px;
}
&:active {
opacity: 0;
}
}
`;
function App() {
return (
<Wrapper>
<Box>
<Emoji>🎅</Emoji>
</Box>
</Wrapper>
);
}
#2.7 Themes
Theme: 모든 색상들을 가지고 있는 하나의 object
-> component의 색깔을 일일이 바꿔주지 않고 object 하나의 색만 바꿔줘도 돼서 편리함
먼저, index.js에서 ThemeProvider 라는 걸 styled-components로부터 import 해줘야 함
import { ThemeProvider } from "styled-components";
ThemeProvider을 theme이라는 prop이 하나 필요함
// index.js
import React from "react";
import ReactDOM from "react-dom";
// import ThemeProvider
import { ThemeProvider } from "styled-components";
import App from "./App";
// 모드별로 컴포넌트를 만들어서 ThemeProvider의 prop인 theme으로 사용하면
// prop 하나만 변경해도 전체 색 변경 가능
const darkTheme = {
textColor: "whitesmoke",
backgroundColor: "black",
};
const lightTheme = {
textColor: "#11111",
backgroundColor: "black",
};
ReactDOM.render(
<React.StrictMode>
{/* ThemeProvider로 App을 감싸서 App 전체에 theme을 적용 */}
<ThemeProvider theme={darkTheme}>
<App />
</ThemeProvider>
</React.StrictMode>,
document.getElementById("root")
);
// App.js
import styled from "styled-components";
const Title = styled.h1`
/* index에서 지정한 컴포넌트 내부 속성명을 불러와 prop 변경 */
/* textColor 변경 */
color: ${(props) => props.theme.textColor};
`;
const Wrapper = styled.div`
display: flex;
height: 100vh;
width: 100vw;
justify-content: center;
align-items: center;
/* backgroundColor 변경 */
background-color: ${(props) => props.theme.backgroundColor};
`;
function App() {
return (
<Wrapper>
<Title>Hello</Title>
</Wrapper>
);
}
export default App;
property 몇 개를 가진 object를 ThemeProvider에 전달하기만 하면 끝
그럼 ThemeProvider 안에 있는 모든 component들은 이 object에 접근할 수 있게 됨
반전해서 사용할 property의 이름은 꼭 같아야 함!
ex) textColor, backgroundColor
'REACT' 카테고리의 다른 글
| 강의 내용 정리 (기초) (1) | 2022.11.18 |
|---|---|
| React에서 레이아웃 만들 때 쓰는 JSX 문법 3가지 (0) | 2022.11.08 |
| React를 사용하는 이유 (0) | 2022.11.08 |
| # 3. State (0) | 2021.10.10 |