Skip to content

Conversation

@Seony-Y
Copy link

@Seony-Y Seony-Y commented Sep 19, 2025

No description provided.

Copy link
Owner

@givvemee givvemee left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

고생하셨습니다. 엄청 빠르게 잘 구현하셨네요!

// 불변성 지키기 => 원본 배열을 그대로 수정하지 않기
const addTodo = () => {
// if(newTodo === "") return; // 공백 입력 방지
// if(!newTodo) return; falsy 값 => 빈문자열 처리 주로 이렇게 사용
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

주석을 꼼꼼하게 잘 활용하시는군요. 좋습니다.

// if(newTodo === "") return; // 공백 입력 방지
// if(!newTodo) return; falsy 값 => 빈문자열 처리 주로 이렇게 사용
if (newTodo.trim() === "") return; // early return
const updatedTodoList = [
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

새로운 배열을 선언하여 업데이트를 한 뒤 setTodoList 에 업데이트 하신 것도 좋습니다. 아래에 주석하셨던 것처럼 spread 연산자를 활용할 수도 있습니다. 방법은 다양하지만 결국 불변성을 지키기 위함이라는 점을 잘 기억하고 계시군요.

// TODO: 4. 할 일 삭제 함수 구현
const deleteTodo = (index) => { };
const deleteTodo = (index) => {
const deletedTodoList = todoList.filter((_, i) => i !== index);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

여기서는 i 만 비교하기 때문에, filter 의 첫번째 _ 는 익명 처리 합니다. 일반적으로 이런 패턴은 크게 쓰이지는 않아요. 그때 설명 드렸던 것처럼, 보통 데이터는 해당 데이터가 가지고 있는 고유 unique key 값을 사용하기 때문에... 이번은 쉬운 단계의 케이스로 생각해 주심 될 것 같습니다. 굿!

const handleKeyDown = (e) => { // event를 받음. keyboradEvent
//console.log(e.key,e.nativeEvent.isComposing);
//if (e.nativeEvent.isComposing) return; // 조합 중이면 무시
if (e.key === "Enter" && !isComposing) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

여기가 잘 동작하나요? 저는 시현 님 브랜치에서 이렇게 보입니다요.

2025-09-24.9.31.45.mov

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아 ... 요거 제가 코멘트를 잘못 달았는데, 이 코멘트는 AdvancedTodo 의 TODO 8 번에 달았어야 할 코멘트입니다. ㅎㅎㅎ 양해를. ...

if (e.key === "Enter" && !isComposing) {
addTodo();
}
// if(e.key !== "Enter") return;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이렇게 early return 처리를 해 주는 방식을 더 많이 사용하기는 합니다.

// TODO: 1. 사용자 입력값을 저장할 state, 현재 필터 상태를 저장할 state, 수정 중인 할 일의 ID와 수정 중인 텍스트를 저장할 state들 생성
const [inputValue, setInputValue] = useState("");
const [filter, setFilter] = useState("all");
const [editId, setEditId] = useState(null);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

초깃값을 빈 값 없이 꼼꼼히 채워주셨구만요.

const deleteCompleteTodos = todoList.filter((todo) => todo.state !== "완료");
setTodoList(deleteCompleteTodos);
}

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

새로 작성해야 하는 함수가 많기는 했지만 .map() 이나 .filter() 의 일관된 사용으로 잘 구현해 주셨습니다. 객체를 업데이트 했을 때에도 { ... todo, ... } 패턴으로 올바르게 처리 되었네요. 좋습니다.

// TODO: 1. 통계 계산
const totalCount = todoList.length;
const completedCount = todoList.filter((todo) => todo.state === "완료").length;
const progress = totalCount === 0 ? 0 : Math.round((completedCount / totalCount) * 100);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const progress = Math.round((completedCount / (totalCount || 1)) * 100) || 0;

이런 식으로도 사용할 수 있겠네요.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants