cra 환경에서 코드를 작성하였습니다.
Github 링크
https://github.com/mokyoungg/react_ts_todolist/blob/master/README.md
React에서 TS 설치하기
출처 : https://create-react-app.dev/docs/adding-typescript/
Create React App과 함께 설치하기
npx create-react-app my-app --template typescript
기존의 CRA 환경에 TS 추가하기
npm install --save typescript @types/node @types/react @types/react-dom @types/jest
이후 모든 파일의 이름을 TypeScript 파일로 변경하고 개발 서버를 재시작.
(src/index.js => src/index.tsx)
React와 TypeScript로 todolist 만들기
프로젝트 초기 설정(App.tsx)

- 파일명은 tsx로 만든다.(App.tsx)
- 해당 함수가(const App = () => {}) react 컴포넌트라는 것을 타입스크립트로 설정한다.
- FC는, FunctionComponent.(함수형 컴포넌트)

- App 함수의 타입을 컴포넌트로 정의한 이후 해당 함수가 일반 함수라면 오류가 발생한다.
타입스크립트에서 props 사용
App.tsx

TodoList.tsx

- App 컴포넌트에서 정의한 todos 라는 배열을 TodoList 컴포넌트에 props로 전달한다.
- TodoList 컴포넌트에선 전달받은 props를 활용하여 페이지를 보여준다.
React에서 사용하는 가장 기본적인 사항이 타입스크립트에서 사용하면 에러가 발생한다.

이는 property 가 존재하기 않기 때문에 컴파일 오류가 발생한것이다.
타입스크립트가 props를 얻고 이를 활용하는 것을 이해하지 못했기 때문이다.
App.tsx에서 TodoList로 props 전달

- App에서 전달되는 props를 타입스크립트로 설정한다.(interface TodoListProps)
- 컴포넌트에 <>를 사용하여 설정한 props를 추가한다.(타입스크립트 제네릭)
- 이를 통해 타입스크립트에선 props를 이해하고 오류를 발생시키지 않는다.
useRef와 타입스크립트(NewTodo 컴포넌트 제작)


- todolist에 해야할 일을 추가하기 위해 NewTodo 컴포넌트를 만들었다.
- 해당 컴포넌트에서 input 태그에 접근하기 위해 useRef를 사용했지만 타입스크립트에서 오류가 발생한다.

- textInputRef가 참조하는 대상이 HTML의 Input 요소라는 것을 알려준다.
- 해당 코드가 실행될 때(처음 컴포넌트가 렌더링될때) null 값을 가지게 된다.
- 렌더링이 되고 나면 연결이 설정되고 해당 참조가 작동하게 된다.(null에서 input 태그로)
컴포넌트간의 커뮤니케이션(state 조작)
NewTodo 컴포넌트에서 작성한 text를 App 컴포넌트의 todos 에 추가한다.
useState 사용하기

- React Hooks의 useState를 사용하려면 해당 state의 타입을 설정해줘야한다.
- todos(state)의 형태는 배열이고, 해당 배열의 요소는 객체이며 객체의 키에 해당하는 id와 text는 string 타입을 가지고 있다.
더 깔끔하게 사용하기(todo.model.ts 의 사용)


- 코드를 깔끔하게 쓰기 위해 Todo라는 interface 를 todo.model.ts라는 파일에서 작성.
- 이후 작성한 인터페이스를 import 하여 사용한다.
함수 전달하기

- todos(state)를 조작하는 todoAddHandler 라는 함수를 자식 컴포넌트인 NewTodo 컴포넌트에 전달한다.
- 처음 props를 전달했을때와 같은 이유로 오류가 발생한다.

- 자식컴포넌트인 NewTodo 컴포넌트에서 props를 정의한다.
- props로 받는 onAddTodo는 함수형 타입이며 인자로 string 타입을 받는다.
- 이제 해당 함수를 props.함수이름 으로 사용할 수 있다.
기능 추가하기(todlist 지우기)

- App 컴포넌트에서 todos(state)이 요소를 지우는 함수인 todoDeleteHandler 라는 함수를 작성함.(filter를 통해 id의 값을 비교하여 같은 id는 지움)
- 해당 함수를 TodoList 컴포넌트에 전달

- 자식 컴포넌트인 TodoList 컴포넌트에서 props로 받아오는 함수의 타입을 정의한다.
- 기존에 작성했던 TodoListProps에서 onDeleteTodo 를 string을 인자로 받는 함수 타입으로 설정
- 해당 함수를 button 태그의 onClick 이벤트로 설정한다.
참조