React Js Master #2 Typescirpt ,interface, optional props, styled.d.ts
TypeScript 셋업
1. Create React App을 타입스크립트로 시작하기
npx create-react-app my-app --template typescript 또는
You are running `create-react-app` 4.0.3, which is behind the latest release (5.0.0). 오류가 뜬다면 아래 명령어로 진행
npx create-react-app@5.0.0 my-app --template typescript
https://create-react-app.dev/docs/adding-typescript
2. 기존 Create React App으로 만든 프로젝트에 타입스크립트 설치
2.1npm install --save typescript @types/node @types/react @types/react-dom @types/jest
+tsconfig.json파일이 없다면 추가로 설정
2.2 js파일 ts와 react의 합인 tsx로 파일명 변경
1 npm start 로 서버 시작
프로젝트의 typescirpt 검사함
typescript가 몇몇의 자바스크립트 기반 라이브러리 이해 못함 예) styled-component, props
-->npm install --save-dev @types/styled-components 명령어 설치해서 typescript한테 styled-component가 무엇인지 설명하기
typescript로 작업할 때 @types Definitely Typed에서 필요 대부분의 type definition들을 얻을 수있다.
https://github.com/DefinitelyTyped/DefinitelyTyped
우리가 전에 사용한 prop-types와 다른 점
propTypes: 코드 실행 후 확인 가능, 브라우저의 콘솔에 경고 표시를 해줌
Typescript: 코드 실행 전에 확인 가능
Interface
interface: typescript의 개념으로 object shape 객체모양을 설명해줌.
circle.tsx
import styled from "styled-components";
const Container = styled.div``;
interface CircleProps { .//컴포넌트의 props의 형태 !
bgColor: string;
}
function Circle({ bgColor }: CircleProps) {
return <Container />;
}
export default Circle;
/*
function Circle(props: CircleProps) {
return <Container bgColor={props.bgColor} />; 이런식으로 사용해도 되지만 보통 위의 형식을 쓴다.
}
*/
app.tsx
import React from "react";
import Circle from "./Circle";
import "./App.css";
function App() {
return (
<div>
<Circle bgColor="teal" />
<Circle bgColor="tomato" />
</div>
);
}
export default App;
component와 style-component에 props 보내기 현재는 한 가지 속성만 있어서 이와 같이 보낼 수 있는 것
import styled from "styled-components";
interface CircleProps {
bgColor: string;
}
const Container = styled.div<CircleProps >`
width: 200px;
height: 200px;
background-color: ${(props) => props.bgColor};
`;
function Circle({ bgColor }: CircleProps) {
return <Container bgColor={bgColor} />;
}
export default Circle;
배운점
1.typescript에서 props와 interface를 사용하여 보호하기
interface는 object설명이다.!
default props , optional props
interface CircleProps {
bgColor: string;
borderColor?: string; //optional
}
function Circle({ bgColor, borderColor }: CircleProps) {
return <Container bgColor={bgColor} borderColor={borderColor ?? bgColor} />; //borderColor 없으면 bgColor
}
?? (Null 병합 연산자 (Nullish coalescing operator))
값이 null이거나 undefined이면 오른쪽 값을, 그렇지 않으면 왼쪽 값을 반환하는 논리연산자
optional props에 undefined때, null일 때를 위하여 기본 값 주기
interface CircleProps {
bgColor: string;
borderColor?: string;
active?:boolean
}
function Circle({ bgColor, borderColor,active=false }: CircleProps) { //active값을 주지 않았을 때 기본으로 false값을 갖게된다.
return (
<Container bgColor={bgColor} borderColor={borderColor ?? bgColor} active={true}>//active true를 준 상황
</Container>
<Container bgColor={bgColor} borderColor={borderColor ?? bgColor} >//active값 주지 않았으므로 false가 됨
</Container>
);
}
app.tsx
function App() {
return (
<div>
<Circle bgColor="teal" borderColor="black" />
<Circle bgColor="tomato" text="bye" /> //값이 있으면 bye로 나오고 없으면 기본값인 hi가 나타남
</div>
);
}
Typescirpt와 React state
useState < number > ( )
state의 type을 지정하려면 Generics안에 타입을 지정
일반적으로는 초기값을 지정하면 타입스크립트가 자동으로 타입을 유추하기 때문에 굳이 지정해주지 않아도 되지만 상태가 undefined또는 null이 될 수도 있거나 객체 또는 배열일 때는 지정해주는 것이 좋다.
ex)
const [ value, setValue ] = useState(0);// 타입스크립트가 자동으로 type을 number라고 유추함
const [ value, setValue ] = useState< Value | null >(null);
import React, { useState } from "react";
function App() {
const [value, setValue] = useState("");
const onChange = (event: React.FormEvent<HTMLInputElement>) => { //어떤 종류의 element가 onChange 이벤트를 발생시킬지 특정 할 수있다.
const {
currentTarget: { value }, //React Js Typescirpt에서는 currentTarget 사용
} = event;
setValue(value);
};
const onSubmit = (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
console.log("hello", value);
};
return (
<div>
<form onSubmit={onSubmit}>
<input
onChange={onChange}
value={value}
type="text"
placeholder="username"
/>
<button>Log in </button>
</form>
</div>
);
}
export default App;
}
https://reactjs.org/docs/events.html
리액트 내의 이 모든 이벤트들에 관해 궁금하다고 한다면
SyntheticEvent라고 불리는 가이드가 있습니다.
ReactJS는 이전에 우리가 보았다시피 자바스크립트의 실제 이벤트를 넘겨주는게 아닙니다.
ReactJS가 어느 다른 방식으로 이벤트들을 최적화 할 수 있는 이벤트인 SyntheticEvent를 주는 겁니다.
1.styled.d.ts 파일 생성하기
https://styled-components.com/docs/api#typescript
2. declaration file 복 붙하기
styled-components: API Reference
API Reference of styled-components
styled-components.com
styled.d.ts파일을 생성해서 styled-components import 한 후
styled components의 테마정의를 확장하는 것
// import original module declarations
import "styled-components";
// and extend them!
declare module "styled-components" {
export interface DefaultTheme {
textColor: string;
bgColor: string;
btnColor:string;
}
}
2.src에 theme.ts 파일 생성 후 테마 만들기
import { DefaultTheme } from "styled-components";
export const lightTheme: DefaultTheme = {
bgColor: "white",
textColor: "black",
btnColor: "tomato",
};
export const darkTheme: DefaultTheme = {
bgColor: "black",
textColor: "white",
btnColor: "teal",
};
index.jsx
import React from "react";
import ReactDOM from "react-dom";
import { ThemeProvider } from "styled-components";
import App from "./App";
import { lightTheme,darkTheme } from "./theme";
ReactDOM.render(
<React.StrictMode>
<ThemeProvider theme={lightTheme}>
<App />
</ThemeProvider>
</React.StrictMode>,
document.getElementById("root")
);
app.js
import React, { useState } from "react";
import styled from "styled-components";
const Container = styled.div`
background-color: ${(props) => props.theme.bgColor};
`;
const H1 = styled.div`
color: ${(props) => props.theme.textColor};
`;
const Btn = styled.button`
background-color: ${(props) => props.theme.btnColor};
`;
function App() {
return (
<div>
<Container>
<H1>protected!</H1>
</Container>
</div>
);
실수로 부터 완전히 보호되어 작성 가능 !