Skip to content

[AIBE6/4팀/정연수] TODO APP 만들기 완료#62

Open
tke0329 wants to merge 2 commits intosik2:mainfrom
tke0329:mission
Open

[AIBE6/4팀/정연수] TODO APP 만들기 완료#62
tke0329 wants to merge 2 commits intosik2:mainfrom
tke0329:mission

Conversation

@tke0329
Copy link

@tke0329 tke0329 commented Mar 19, 2026

TODOLIST

React, TypeScript 사용

  • 데이터 CRD 구현
TodoList.mov
  • dummy json api 연동
  • context 적용
  • ui 짱 못생김
  • 작성시간 구현
  • 진행중인 할 일, 완료된 할 일 BrowserRouter, Link 페이지 구분

@gemini-code-assist
Copy link

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

이 PR은 React와 TypeScript를 사용하여 기본적인 할 일(Todo) 애플리케이션을 완성하는 미션의 결과물입니다. 핵심 CRUD 기능 구현, 외부 더미 API 연동을 통한 데이터 초기화, React Context API를 활용한 효율적인 상태 관리, 그리고 react-router-dom을 이용한 페이지별 할 일 목록 필터링 기능에 중점을 두었습니다. 이를 통해 사용자는 할 일을 추가, 삭제, 완료 처리하고, 진행 상태에 따라 목록을 쉽게 확인할 수 있습니다.

Highlights

  • 데이터 관리: 할 일(Todo) 데이터에 대한 생성(Create), 읽기(Read), 삭제(Delete) 기능을 구현했습니다.
  • 외부 API 연동: 더미 JSON API를 사용하여 초기 할 일 데이터를 가져오도록 연동했습니다.
  • 상태 관리: React Context API를 활용하여 전역 상태 관리를 적용했습니다.
  • 라우팅: react-router-dom을 사용하여 진행 중인 할 일과 완료된 할 일을 별도의 페이지로 구분했습니다.
  • 작성 시간: 각 할 일의 작성 시간을 표시하는 기능을 추가했습니다.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

이 PR은 React, TypeScript, React Router를 사용하여 TODO 앱의 좋은 기반을 마련했습니다. 상태 관리를 위해 Context API를 사용한 것은 좋은 선택입니다. API 데이터 처리와 관련하여 버그로 이어질 수 있는 몇 가지 심각한 문제를 발견했습니다. 또한 코드 명확성과 유지보수성을 개선하기 위한 몇 가지 의견을 남겼습니다. 제 제안을 검토해 주세요.

useEffect(() => {
fetch('https://dummyjson.com/todos')
.then(res => res.json())
.then(data => setTodos(data.todos))

Choose a reason for hiding this comment

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

critical

초기 데이터를 처리하는 방식에 두 가지 심각한 문제가 있습니다:

  1. date 속성 누락: dummyjson API 응답에는 Form 인터페이스에 필요한 date 필드가 포함되어 있지 않습니다. 이로 인해 formatDate가 호출될 때 런타임 오류가 발생할 수 있습니다. 가져온 각 todo 항목에 date를 추가해야 합니다.
  2. ID 충돌: lastId가 올바르게 초기화되지 않았습니다. 새 todo를 추가할 때 중복 ID가 생성되는 것을 방지하려면 가져온 데이터의 최대 ID를 기반으로 설정해야 합니다.

두 문제를 모두 해결하기 위한 제안입니다.

            .then(data => {
                const initialTodos = data.todos.map((todo: any) => ({ ...todo, date: Date.now() }));
                setTodos(initialTodos);
                if (initialTodos.length > 0) {
                    lastId.current = Math.max(...initialTodos.map((t: Form) => t.id)) + 1;
                }
            })

return (
<ul>
{filteredTodos.map(e => (
<TodoItems todos={e}/>

Choose a reason for hiding this comment

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

high

React에서 리스트를 렌더링할 때는 각 항목을 고유하게 식별하기 위해 key prop이 필요합니다. 이는 성능에 중요하며, 리스트 내에 상태를 가진 컴포넌트가 있을 때 버그를 방지합니다. <TodoItems /> 컴포넌트에 todo의 ID를 사용하여 고유한 key를 추가해주세요.

Suggested change
<TodoItems todos={e}/>
<TodoItems key={e.id} todos={e}/>

<Link to="/list/active">진행중인 목록</Link>
<Link to="/list/completed">완료된 목록</Link>
</nav>
<div className="b2">

Choose a reason for hiding this comment

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

medium

CSS 클래스 이름 b2는 의미를 알기 어렵습니다. 클래스에 content-wrappermain-content처럼 의미 있는 이름을 사용하면 코드를 읽고 유지보수하기가 더 쉬워집니다.

Suggested change
<div className="b2">
<div className="main-content">

Comment on lines +5 to +9
interface ItemProps {
todos: Form;
}

const TodoItems = ({todos}:ItemProps) => {

Choose a reason for hiding this comment

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

medium

이 컴포넌트의 todos prop은 단일 todo 항목을 나타내지만 이름이 복수형이라 오해의 소지가 있습니다. 가독성을 높이기 위해 단수형인 todo로 이름을 바꾸는 것이 좋습니다. 또한 컴포넌트 내에서 todos.todo.로 모두 수정해야 합니다.

Suggested change
interface ItemProps {
todos: Form;
}
const TodoItems = ({todos}:ItemProps) => {
interface ItemProps {
todo: Form;
}
const TodoItems = ({todo}:ItemProps) => {



const addTodo = (text: string) => {
setTodos([{id: lastId.current, todo:text , completed:false, date: Date.now()}, ...todos])

Choose a reason for hiding this comment

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

medium

이전 상태를 기반으로 상태를 업데이트할 때는 setState의 함수형 업데이트 형태를 사용하는 것이 더 안전합니다. 이렇게 하면 항상 최신 상태를 기반으로 작업하게 되어 잠재적인 경쟁 상태를 피할 수 있습니다.

        setTodos(prevTodos => [{id: lastId.current, todo:text , completed:false, date: Date.now()}, ...prevTodos])

Comment on lines +22 to +25
div {
display: flex;
flex-direction: row;
}

Choose a reason for hiding this comment

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

medium

div와 같은 광범위한 요소 선택자를 스타일링에 사용하면 애플리케이션 전체에 의도하지 않은 부작용을 일으킬 수 있습니다. 특히 컴포넌트 기반 아키텍처에서는 충돌을 피하기 위해 특정 클래스 이름을 사용하여 스타일의 범위를 지정하는 것이 좋습니다.

Comment on lines +1 to +10
import InputForm from "../component/InputForm.tsx";

const Form = () => {

return (
<InputForm></InputForm>
)
}

export default Form; No newline at end of file

Choose a reason for hiding this comment

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

medium

Form 컴포넌트는 InputForm 컴포넌트를 감싸는 역할만 합니다. 이는 불필요한 추상화 계층을 추가합니다. 이 컴포넌트를 제거하고 Home.tsx에서 InputForm을 직접 사용하면 코드를 단순화할 수 있습니다.

@@ -0,0 +1,7 @@

export interface Form {

Choose a reason for hiding this comment

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

medium

인터페이스 이름 Form은 폼이 아닌 단일 "todo" 항목을 나타내므로 혼동을 줄 수 있습니다. Todo로 이름을 변경하면 코드를 더 직관적이고 이해하기 쉽게 만들 수 있습니다. 이 이름 변경은 이 타입을 사용하는 다른 파일들의 업데이트를 필요로 합니다.

Suggested change
export interface Form {
export interface Todo {

@@ -0,0 +1,12 @@

const formatDate = (date) => {

Choose a reason for hiding this comment

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

medium

date 매개변수는 암시적으로 any 타입을 가집니다. TypeScript 프로젝트에서는 타입 안정성과 코드 명확성을 높이기 위해 함수 매개변수에 명시적으로 타입을 지정하는 것이 좋습니다.

Suggested change
const formatDate = (date) => {
const formatDate = (date: number | Date) => {

Copy link

@Rakhyunn Rakhyunn left a comment

Choose a reason for hiding this comment

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

오히려 UI가 화려하지 않아서 눈이 덜 피로하고 좋은데요?
그리고 필터 기능을 적용하여서 Todo를 관리할 수 있는 부분이 좋은 거 같습니다!
필터는 페이지 이동보다는 UI 상태 전환에 가깝다고 생각해서 TodoList에서 상태로 관리해서 리스트 목록만 바꾸는 방식이 페이지 이동도 잦지 않아 자연스러운 것 같은데 연수님 생각도 궁금합니다! 🧐
고생하셨습니다! 👍

@haxxru
Copy link

haxxru commented Mar 19, 2026

할 일 목록/완료된 것/미완료된 것으로 탭을 나누어 두신 게 상당히 인상깊습니다!
심플하고 보기 좋은 거 같아요
수고하셨습니다!

@tke0329
Copy link
Author

tke0329 commented Mar 20, 2026

@Rakhyunn BrowserRouter 를 적용하는것 부터 해서 이후 여러 항목을 페이지로 분기하는것에 포커스를 두었는데 TodoList 앱에서는 리스트 목록만 바꾸는 방식으로 작업하는 방법이 더 효율적이고 좋은 방법 같습니다! 좋은 의견 감사합니다 ㅎㅎ

@Sinou3936
Copy link

기능적인 면에서는 조금 아쉬운게 데이터 넣고 중복 처리 된 게 아쉽네요 중복 처리 되는게 의도 한 것 일수 도 있지만 중복은 피해 주셨으면 하네요
그리고 심플한게 최고로 좋긴 하죠, 메뉴 탭 나눠서 처리 하는것도 좋긴 하네요 소스 짜신다고 고생하셨어요

@tke0329
Copy link
Author

tke0329 commented Mar 20, 2026

@Sinou3936 네 ㅎ 고유 id 값이 api에서 가져온 값이랑 겹쳐서 데이터가 중복처리 되는걸 어떻게 처리해야할지 잘 모르겠습니다 조금 더 공부해보겠습니다 감사합니다 ㅎ

@m1nhy2uk
Copy link

페이지 분리를 진행중인 것과 완료된 것으로 분리한 것이 조금 더 다듬으면 실용성이 좋아보입니다
고생하셨습니다

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.

5 participants