const todoList: string[] = ['todo1', 'todo2', ...]
// 형태의 데이터를 아래와 같이 수정하였다.
const todoList: { id: string; done: boolean; content: string }[] = [
{
id : 'uuidv4',
done: false,
content: 'todo1',
},
{
id : 'uuidv4',
done: true,
content: 'todo2',
},
];
//완료 여부를 done에 지정된 boolean 값으로 판단한다.
string[]
이였다. 말 그대로 문자열로 이루어진 배열이였고, todo와 done 을 나누고 저장하는 데에 두 가지 상태를 이용했다.id
, done
, content
로 각각 uuid 와 완료여부, 본문을 저장하는 역할을 하게끔 했다.interface
를 하나 더 작성하여 참조하는 방법이였다.// App.tsx
interface ITodo {
id: string;
done: boolean;
content: string;
}
const [todoList, setTodoList] = useState<ITodo[]>([]);
// ITodo[] 는 위의 타입을 가진 객체의 배열을 나타낸다.
→ 나는 일단 인터페이스인 ITodo
를 필요한 모든 컴포넌트에 일일히 전부 선언해주었는데, 이런 수동적인 방법보단 한 곳에 타입을 저장하고 꺼내어 쓰는 방법이 무조건… 있을 것 같다.
const [todoList, setTodoList] = useState<
{ id: string; done: boolean; content: string }[]
>([]);
ITodo
인터페이스를 만들어 사용했다.interface ITodo {
id: string;
done: boolean;
content: string;
}
interface IProps {
todoList: ITodo[];
setTodoList: Dispatch<SetStateAction<ITodo[]>>;
}
interface IProps {
todoList: { id: string; done: boolean; content: string }[];
setTodoList: Dispatch<
SetStateAction<{ id: string; done: boolean; content: string }[]>
>;
}
→ props를 이용하는 다른 컴포넌트 들도 위와 동일하게 처리했다.
map
과 filter
를 이용하여 컴포넌트 들을 렌더링하면 됐지만, 수정 후에는 하나의 상태에 저장되므로, 방식의 변경이 필요했다.filter
를 이용하여 처리했다.const todos: ITodo[] = todoList.filter((todo) => !todo.done);
const dones: ITodo[] = todoList.filter((todo) => todo.done);
// 변수에도 타입 지정 잊지않기!
// todo.done 의 boolean 값을 이용한다.
map
을 이용하여 컴포넌트를 렌더링 해주었다.{todos.map((todo, idx) => { // or dones.map
return (
<Todo // or Done
key={idx}
id={todo.id}
content={todo}
todoList={todoList}
setTodoList={setTodoList}
/>
);
})}
{todos.length === 0 && <div className="empty">비어 있습니다.</div>}
// or dones
id
프로퍼티를 추가하고, 해당하는 id 를 uuid 라이브러리를 이용하여 지정해주는 방식으로 수정하였고, 코드는 아래와 같이 수정하였다.const deleteTodo = () => {
setTodoList(
todoList.filter((todo) => {
return todo.id !== uuid;
})
);
};
→ 비교하는 것이 id
일 뿐, 결과적으로 흐름은 동일하다.
done
이 true
인 항목을 제외하는 방향으로 수정해주어야했다.const clearDoneList = () => {
setTodoList(
todoList.filter((todo) => {
return todo.done === false;
})
);
};
해당하는 타입을 가진 객체
를 가진 배열
이라고 생각해보니 이해가 되었다!string[]
이랑 다를게 없다는 얘기