React + TS의 조합에 조금 익숙해지기 위해 간단한 Todo List를 만들며 조금 더 알아보고 싶은 내용을 정리해 보도록 하겠다.
yarn creat react-app todo --typescript
를 통해 react 개발을 위한 환경을 만들어 주고, App.tsx
, index.tsx
, react-app-env.ts
,빼고는 다 지워준다.
이제 만들 준비가 된듯 하다.
이 과정에서 하나 신기한게 있었는데 TodoItemCard.ts
로 파일을 생성했더니 react 관련 코드가 먹히지 않아서 적잖히 당황을 했는데, 설마...하면서 TodoItemCard.tsx
로 바꾸니 잘 작동했다 🤦♂️
알기론 js 파일은 컴파일 과정에서 jsx파일로 바뀌고 ts 파일은 tsx로 바뀌는 걸로 알고있었는데...잘못 알고 있었나보다..(js 에선 .js로 해도 잘 돌아감..)
여튼 코드를 보자.
import React from 'react';
import {Todo} from '../types'
import './TodoItemCard.styled.css'
interface TodoItemCardProps {
todo : Todo;
}
export const TodoItemCard: React.FC<TodoItemCardProps> = ({ todo }) =>{
return (
<li>
<label className = {todo.complete ? "complete" : undefined}>
<input type= "checkbox" checked={todo.complete}/>
{todo.text}
</label>
</li>
)
}
FC는 이전 포스팅에서 다뤘고 저기 타입 설정에 interface
부분을 알아보도록 하자.
interface
는 Java나 c#에 나오는 정적 타입 언어에서 많이 쓰이는 개념이라 아주 익숙하지는 않다..😅
interface
는 구현부가 빠진 클래스 느낌이다. 즉, 대충 어떤 객체가 이런저런 파라미터, 메소드를 가진다고 선언하는 것이다.
import React from 'react';
import { TodoItemCard } from './components/TodoItemCard'
import {Todo} from './types'
const todos : Array<Todo> = [{text : "pop a pill ", complete : true}, {text : "eat dinner ", complete : false}]
const App : React.FC = () => {
return (
<>
<TodoItemCard todo ={todos[0]}/>
<TodoItemCard todo ={todos[1]}/>
</>
);
}
export default App;
이렇게 해서 먼저 todos에 더미 데이터를 넣고 컴포넌트를 불러오면
이런 모양이 만들어 진다.
types 파일은 App.tsx
, TodoItemCard
에 같이 쓰이기 때문에 따로 빼서 todo의 타입을 불러와 사용했다.
export type Todo = {
text : string;
complete: boolean;
};