React에서 파일이 많아지면 데이터 처리하는데에 오래걸리기 때문에 이것을 최소화 하고자 라이브러리를 사용한다고 한다.
우리가 오늘 공부해볼 CSS라이브러리
의 종류에는 여러가지가 있는데, 가장 많이들 사용하는 것은 talewind
라는 라이브러리이다. 하지만 이 라이브러리는 가독성이 좋지 않아서 우리는 styled components
를 사용하기로 했다.
styled-components의 가장 큰 장점은 태그의 이름을 정할 수 있다는 것이다.
즉, div 대신에 내가 지정한 이름을 사용할 수 있다는 것이다.
const Wrapper = styled.div``;
이렇게 div의 이름을 선언해주면 아래와 같이 div 대신에 Wrapper를 사용할 수 있다.
<Wrapper>
<div>Numbers!</div>
</Wrapper>
이 라이브러리는 css 라이브러리인 만큼 꾸밀 수도 있는데, 백틱 사이에 꾸밈요소를 작성해주면 된다.
const Wrapper = styled.div`
background-color: teal;
text-align: center;
`;
같은 이름의 태그를 여러 개 사용하는데, 꾸밈요소 중 한 가지만 다르고 나머지는 같게 하고 싶을 때, 모든 꾸밈요소를 다 적어주면 코드가 효율적이지 못하다.
그래서 특정 요소만 props로 전달해주고, 나머지 공통 요소들은 백틱 사이에 적어주면 된다.
const Title = styled.div<{textColor: string}>`
font-size: 80px;
font-weight: 900;
color: ${(props) => props.textColor};
`;
위 코드는 textColor을 제외한 나머지 font-size, font-weight는 동일하게 적용한 것이다.
아래와 같이 textColor만 따로 지정해줄 수 있다.
<Wrapper>
<Title textColor="tomato">Numbers!</Title>
<Title textColor="white">Numbers!</Title>
</Wrapper>
이렇게 코드를 작성하면,
이렇게 textColor을 제외한 모든 요소가 동일한 두 개의 태그를 볼 수 있다.
먼저, styled-components를 깔아주기 위해서 터미널에 아래와 같이 작성해준다.
npm i styled-components
깔아준 styled-components를 내 코드에 연결해주기 위해서 코드 맨 처음에 import를 해줘야 한다.
import styled from "styled-components";
그 후에, 백틱 사이에 꾸밈요소를 넣어주는 것을 vs코드가 인식할 수 있게 해주기 위해서 확장자를 깔아줘야 한다. 아래와 같은 확장자를 깔아주면 된다.
import { useEffect, useState } from "react";
import styled from "styled-components";
//styled-components 사용
const Wrapper = styled.div`
background-color: teal;
text-align: center;
`;
const Title = styled.div<{textColor: string}>` //<{props: type}>
font-size: 80px;
font-weight: 900;
color: ${(props) => props.textColor};
`;
function App() {
//ts코드를 작성
const [answer, setAnswer] = useState(0);
const [life, setLife] = useState(5);
const [userAns, setUserAns] = useState("");
const [hint, setHint] = useState("Guess");
const [isCor, setIsCor] = useState(false);
useEffect(() => {
setAnswer(Math.floor(Math.random() * 100));
}, []);
const handleOnChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setUserAns(e.target.value); //event 안에 target 안에 있는 value를 받아야 함
};
const handleOnSubmit = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault(); //event가 실행될 때마다 창이 새로고침되는 것을 막음
setLife((prev) => prev - 1);
if(Number(userAns) === answer){
setIsCor(true);
} else{
if(Number(userAns) > answer){
setHint("Down");
} else{
setHint("Up");
}
}
check();
};
const check = () => {
if(life === 1){
setIsCor(true);
setUserAns(`Game Over, The answer is ${answer}`);
}
}
return (
//html 코드를 작성
<Wrapper>
<Title textColor="tomato">Numbers!</Title>
<Title textColor="white">Numbers!</Title>
<div className="answer">{isCor ? userAns : "?"}</div>
<form onSubmit={(e) => handleOnSubmit(e)}>
<input type="number" onChange={(e) => handleOnChange(e)}/>
<button>submit</button>
</form>
<div>{life}</div>
<div>{hint}</div>
</Wrapper>);
}
export default App; //마지막에 내용들을 내보내기 위해 export를 해줘야 함
나머지 숫자게임 작동 방식은 이전 포스트와 동일하다.