728x90
반응형

개인 과제로 타입스크립트 를 사용한 리액트 todolist를 만들어보았다

시작은 yarn create react-app (이름은 아무거나) --template typescript

useState 사용후 제네릭을 이용해 타입 지정

맵으로 뿌려주는데 불리언 타입은 적용이 안되서 toString 으로 해결

key값을 부여하는데 number는 들어갈수가 없다고 합니다

스트링 타입을 부여해서 해결
<div>
<h1>할일 목록</h1>
<ul>
{todos
.filter((todo) => todo.isDone === false)
.map((todo) => (
<div
key={String(todo.id)}
style={{
border: "1px solid black",
margin: "20px",
}}
>
<h3>{todo.title}</h3>
<p> {todo.contents}</p>
<p> 완료 여부 : {todo.isDone.toString()}</p>
</div>
))}
</ul>
</div>
필터를 이용해 할일 완료 미완료도 구분지어 준다

타입 오류가 뜬다
<form
onSubmit={(event) => {
event.preventDefault();
const newTodo = {
id: 1,
title: title,
contents: contents,
isDone: false,
};
setTodos([...todos, newTodo]);
}}
>
제목
<input
value={title}
onChange={(event) => {
setTitle(event.target.value);
}}
/>
내용
<input
value={contents}
onChange={(event) => {
setContents(event.target.value);
}}
/>
<button>입력 </button>
</form>
대괄호 안에 안넣어 줘서 생기는 오류였습니다,일반 리액트였다면 뜨지않았을 오류인데
타입스크립트라서 실행전에 미리 잡아줬습니다

정상적으로 잘 입력되니 이제
삭제와 완료 버튼까지 만들어 봐야겠습니다

삭제버튼을 만들기위해 고유값은 uuid 를 yarn add react-uuid 통해 받은후 사용해봅니다
<h3>{todo.title}</h3>
<p> {todo.contents}</p>
<p> 완료 여부 : {todo.isDone.toString()}</p>
<button>완료</button>
<button
onClick={() => {
const deletedTodos = todos.filter((item) => {
return item.id !== todo.id;
});
setTodos(deletedTodos);
삭제 버튼 생성

완료 버튼 생성 고유 아이디 값이 동일하면 isDone을 반전시키는 코드를 사용했다

타입스크립트 사용한 todolist 완성이다
import React, { useState } from "react";
import uuid from "react-uuid";
function App() {
type Todos = {
id: string;
title: string;
contents: string;
isDone: Boolean;
};
const [title, setTitle] = useState<string>("");
const [contents, setContents] = useState<string>("");
const [todos, setTodos] = useState<Todos[]>([
{
id: uuid(),
title: "타입 스크립트 ",
contents: "제네릭 연습하기 ",
isDone: false,
},
{
id: uuid(),
title: "타입스크립트 과제",
contents: "타입스크립트에 접목해서 todolist 만들기",
isDone: true,
},
]);
return (
<div>
<header>
<h1>Type Script TodoList </h1>
</header>
<main style={{ backgroundColor: "#fcf6bd" }}>
<div>
<form
onSubmit={(event) => {
event.preventDefault();
const newTodo = {
id: uuid(),
title: title,
contents: contents,
isDone: false,
};
setTodos([...todos, newTodo]);
}}
>
제목
<input
value={title}
onChange={(event) => {
setTitle(event.target.value);
}}
/>
내용
<input
value={contents}
onChange={(event) => {
setContents(event.target.value);
}}
/>
<button>입력 </button>
</form>
</div>
<div>
<h1>할일 목록</h1>
<ul>
{todos
.filter((todo) => todo.isDone === false)
.map((todo) => (
<div
key={String(todo.id)}
style={{
border: "1px solid black",
margin: "20px",
}}
>
<h3>{todo.title}</h3>
<p> {todo.contents}</p>
<p> 완료 여부 : {todo.isDone.toString()}</p>
<button
onClick={() => {
const newTodos = todos.map((item) => {
if (item.id === todo.id) {
return {
...item,
isDone: !item.isDone,
};
} else {
return item;
}
});
setTodos(newTodos);
}}
>
완료
</button>
<button
onClick={() => {
const deletedTodos = todos.filter((item) => {
return item.id !== todo.id;
});
setTodos(deletedTodos);
}}
>
삭제
</button>
</div>
))}
</ul>
</div>
<div>
<h1>완료된 목록</h1>
<ul>
{todos
.filter((todo) => todo.isDone === true)
.map((todo) => (
<div
key={String(todo.id)}
style={{
border: "1px solid black",
margin: "20px",
}}
>
<h3>{todo.title}</h3>
<p> {todo.contents}</p>
<p> 완료 여부 : {todo.isDone.toString()}</p>
<button
onClick={() => {
const newTodos = todos.map((item) => {
if (item.id === todo.id) {
return {
...item,
isDone: !item.isDone,
};
} else {
return item;
}
});
setTodos(newTodos);
}}
>
완료취소
</button>
<button
onClick={() => {
const deletedTodos = todos.filter((item) => {
return item.id !== todo.id;
});
setTodos(deletedTodos);
}}
>
삭제
</button>
</div>
))}
</ul>
</div>
</main>
</div>
);
}
export default App;
생각보다 타입스크립트 적용이 간단한 편이였고 대괄호 생략했을때 오류를 바로 잡아줘서
규모가 큰 프로젝트라면 확실히 일반 JS보다는 편할거같다 익숙해지면 오히려 타입스크립트를 더 애용할지도
728x90
반응형
'Today I Learned (TIL)' 카테고리의 다른 글
TIL 23.12.20 [udemy] React 완벽 가이드 with Redux, Next.js, TypeScript (1) | 2023.12.20 |
---|---|
Next.js 기초 23.12.19 (1) | 2023.12.19 |
23.12.17 TIL (0) | 2023.12.17 |
23.12.16 TIL (0) | 2023.12.16 |
React Query 개념 정리 23.12.15 (0) | 2023.12.15 |