2021. 12. 7. 23:55ㆍNomadCoders/React JS 챌린지
# 학습 전 나의 상태
어제 스타일컴포넌트를 배우고 CSS를 사용할 때보다 더욱 활용하기 쉬움을 알게되었다.
실은,, 코드스테이츠에서 파이널 프로젝트 할 때 사용해봤다. ㅋ..
그래서 다시 한 번 보며서 그 때 이해하지 못했던 부분들을 이해하려고 노력했던 것 같다.
props를 전달하는 방법과 반복되는 코드들을 불러와서 적용시키는 방법등 유용한 것들을 많이 배웠다.
오늘은 처음으로 typescript를 접한다.
어떻게 사용하는 것인지 내심.. 기대도 되고 새로운 것이라 긴장도 된다.
잘 정리해서 공부해봐야지..!
# 오늘의 학습 내용
TYPESCIPT 란?
- JavaScript를 기반으로 한 프로그래밍 언어 ( 다른 프로그래밍 언어!)
- Strongly-Typed 언어이다.
- Strongly-Typed 는 프로그래밍 언어가 작동하기 전에 type을 확인한다는 것
- 아래 예제를 보면 JavaScript는 a, b가 어떤 타입인지 모른채 그냥 결과만 보여준다.
const plus = (a, b) => a + b; plus(1, 2); // 3
- 아래 예제로 보면 조금 더 알 수 있다.
plus(1, "hi"); // "1hi"
- 이렇게 입력된 매개변수를 집어넣는 것 뿐이다.
- 그렇다면 a는 항상 number, b도 항상 number로 알려주고 싶다면 어떻게 할까?
- 바로 타입스크립트를 사용하면 가능해진다. 아래 예제로 살펴보자
const plus = (a:number, b:number) => a + b;
- 이렇게 하면 타입스크립트는 a, b의 타입을 알려주고, 다른 타입이 입력될 시 문제가 있다고 알려줄 것이다.
TYPESCRIPT 만들기
npx create-react-app my-app --template typescript
styled-components 설치하기
먼저 styled-components 설치한다.
npm i styled-component
그리고 타입정의를 받는다.
npm install --save @types/styled-components
참고
https://www.npmjs.com/package/@types/styled-components
@types/styled-components
TypeScript definitions for styled-components
www.npmjs.com
https://velog.io/@hwang-eunji/styled-component-typescript
Styled-component #3 with typescript
오늘은 글로벌 스타일 적용하고, 스타일 컴포넌트에 타입 적용하는 방법을 해보겠돠.하루에 아조조~금씩🔨 야금야금🔨npm i styled-componentnpm i -D @types/styled-componentsstyled-components를 사용할때 보통
velog.io
typing the porps
App.tsx에서 Circle이라는 컴포넌트로 bgColor를 전달하려고 한다.
import Circle from './Circle';
function App() {
return (
<div>
<Circle bgColor="red" />
<Circle bgColor="blue" />
</div>
);
}
다음 Circle 함수에서 bgColor를 받는다.
import React from 'react'
import styled from 'styled-components';
const Container = styled.div`
width: 200px;
height: 200px;
border-radius: 100px;
background-color: ${props => props.bgColor}
`;
function Circle({ bgColor }) {
return (
<Container bgColor={bgColor} />
)
}
export default Circle
이렇게 하면 타입스크립트가 아래 부분에 문제가 있다고 알려준다.
그럼 어떻게 해야할까?
bgColor에 타입을 알려줘햔다. 그렇게 하기 위해서 interface를 사용할 것인데
object shape를 타입스크립트에게 설명해 주기 위함이다.
interface CircleProps {
bgColor: string;
}
이렇게 interface 안에 object shape를 타입스크립트에 알려준다.
function Circle({ bgColor }: CircleProps) {
return (
<Container bgColor={bgColor} />
)
}
스타일컴포넌트에도 props를 전달해 주어야 한다.
const Container = styled.div<CircleProps>`
width: 200px;
height: 200px;
border-radius: 100px;
background-color: ${props => props.bgColor}
`;
div 뒤에 <CircleProps>를 넣어주어 타입스크립트에게 Container가 bgColor를 받을 것이라고 알려준다.
최종 코드는 아래와 같다.
import React from 'react'
import styled from 'styled-components';
interface CircleProps {
bgColor: string;
}
const Container = styled.div<CircleProps>`
width: 200px;
height: 200px;
border-radius: 100px;
background-color: ${props => props.bgColor}
`;
function Circle({ bgColor }: CircleProps) {
return (
<Container bgColor={bgColor} />
)
}
export default Circle
Optional Props
위에 원에만 border 색을 주고 싶다
App.tsx에 첫번째 Circle에 borderColor값을 넣어준다.
function App() {
return (
<div>
<Circle borderColor="red" bgColor="wheat" />
<Circle bgColor="blue" />
</div>
);
}
기본적으로 interface 안에 입력한 object는 repuired 상태인데
이렇게 되면 한 컴포넌트에만 값을 넣어줄 수가 없다.
그래서 아래와 같이 optional 상태로 변경해준다.
interface CircleProps {
// required 상태
bgColor: string;
// optional 상태
borderColor?: string;
}
이렇게하고 스타일컴포넌트에 border 값을 넣어주고 props를 입력한다.
const Container = styled.div<ContainerProps>`
width: 200px;
height: 200px;
border-radius: 100px;
background-color: ${props => props.bgColor};
border: 3px solid ${props => props.borderColor};
`
또 ContainerProps에 borderColor를 타입스크릅트에게 알려준다.
interface ContainerProps {
bgColor: string;
borderColor: string;
}
이제 Circle 함수 안에 Container에 borderColor 값을 넣어준다.
function Circle({ bgColor, borderColor }: CircleProps) {
return (
<div>
<Container bgColor={bgColor} borderColor={borderColor} />
</div>
)
}
그런데 여기서 문제가 있다고 알려준다.
borderColor 뒤에 ?? "white"를 입력해준다.
<Container bgColor={bgColor} borderColor={borderColor ?? "white"} />
이것이 뜻하는 것은
borderColor가 undefined 상태하면 white 값을 가진다하고 표현한다.
import styled from 'styled-components';
interface ContainerProps {
bgColor: string;
borderColor: string;
}
const Container = styled.div<ContainerProps>`
width: 200px;
height: 200px;
border-radius: 100px;
background-color: ${props => props.bgColor};
border: 3px solid ${props => props.borderColor};
`
interface CircleProps {
// required 상태
bgColor: string;
// optional 상태
borderColor?: string;
}
function Circle({ bgColor, borderColor }: CircleProps) {
return (
<div>
<Container bgColor={bgColor} borderColor={borderColor ?? "white"} />
{/* borderColor는 사용자가 만든 borderColor 값이고,
borderColor가 undefined 상태라면 white 값을 줘라 */}
</div>
)
}
export default Circle
추가로 새로운 porps를 만들어본다.
text를 optional로 해서 default 값을 주고 props를 전달하는 곳에만 I'm here가 뜨도록 해보려고 한다.
App.tsx
import Circle from './Circle';
function App() {
return (
<div>
<Circle borderColor="red" bgColor="wheat" />
<Circle text="I'm here" bgColor="blue" />
</div>
);
}
Circle.tsx
interface CircleProps {
// required 상태
bgColor: string;
// optional 상태
borderColor?: string;
text?: string;
}
function Circle({ bgColor, borderColor, text = "default text" }: CircleProps) {
return (
<div>
<Container bgColor={bgColor} borderColor={borderColor ?? "white"}>
{/* borderColor는 사용자가 만든 borderColor 값이고,
borderColor가 undefined 상태라면 white 값을 줘라,
*/}
{text}
</Container>
</div>
)
}
CircleProps에 text?: string;을 넣어주고
Circle 함수에 text = "default text"를 넣고
Container 태그 안에 text를 넣어준다.
이렇게 하면 아래와 같이 text를 props로 전달하지 않은 첫번재 원에는
defaut 값인 default text 가 두번째 원에는 props로 text를 전달해 I'm here가 나온다.
State
function Circle({ bgColor, borderColor }: CircleProps) {
// typeScript를 쓰지 않았더라도 default 값으로 어떤 타입을 쓸건지 안다.
const [counter, setCounter] = useState(0);
setCounter(1);
setValue("hi"); // errer
// 만약 string이 number로 바뀌어야 한다면
const [value, setValue] = useState<number | string>(0);
setValue(0);
setValue("hi");
setValue(true) // errer
Forms
import { useState } from "react";
function App() {
const [value, setValue] = useState("")
const onChange = (e: React.FormEvent<HTMLInputElement>) => {
// TypeScript는 Element에 currentTarget 사용을 택함.
const {
currentTarget: { value }
} = e;
setValue(value);
}
const onSubmit = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
console.log("Hello", value);
}
return (
<div>
<form onSubmit={onSubmit}>
<input
value={value}
onChange={onChange}
type="text"
placeholder="username"
/>
<button>Log in</button>
</form>
</div>
);
}
export default App;
자바스크립트와 리액트를 사용해 만드는 것과 같다.
다만 event를 적용할 때
input에는 React.FormEvent<HTMLInputElement>
form에는 React.FormEvent<HTMLFormElement>
를 넣어줘야 하는 것과
target이 아닌 currentTarget을 사용한다는 점을 잘 기억해야겠다.
# 학습을 마치며
처음으로 배운 타입스크립트이다.
앞으로 챌린지를 진행하면서 계속해서 다루겠지만 아직까지는 생소하다.
강의 잘 보고 잘 따라하면서 학습해서 공부해야겠다.
그리고 타입스크립트로 인해 타입에 대한 문제가 발생하면 렌더링 전에 확인하고 수정할 수 있다는 것이 좋은 것 같다.
실수가 많이 줄어들 것 같아서 좋다!
진작 공부할 것을.. 너무 미룬것 같기도.. 암튼 이번에도 재미있게 해보자!