Skip to content

[AIBE6/1팀/박흥준] TODO APP 만들기 완료#49

Open
HeungJunBag wants to merge 25 commits intosik2:mainfrom
HeungJunBag:main
Open

[AIBE6/1팀/박흥준] TODO APP 만들기 완료#49
HeungJunBag wants to merge 25 commits intosik2:mainfrom
HeungJunBag:main

Conversation

@HeungJunBag
Copy link

@HeungJunBag HeungJunBag commented Mar 18, 2026

React Todo App

React와 Vite로 만든 할 일 관리 앱입니다.

실행 화면

기본 화면 할 일 추가 수정 모드
screenshot_main screenshot_add screentshot_edit

주요 기능

  • 할 일 추가 / 삭제 / 수정
  • 완료 체크 및 취소선 표시
  • 전체 완료 / 전체 해제
  • 남은 할 일 개수 표시
  • LocalStorage를 이용한 데이터 영속성

기술 스택

  • React 19 — UI 구성
  • Vite 8 — 빌드 도구
  • Tailwind CSS v4 — 스타일링
  • Context API — 전역 상태 관리
  • LocalStorage — 데이터 저장

프로젝트 구조

src/
├── App.jsx                  # 루트 컴포넌트
├── main.jsx                 # 엔트리 포인트
├── index.css                # Tailwind CSS 임포트
├── components/
│   ├── TodoWriteForm.jsx    # 할 일 입력 폼
│   ├── TodoList.jsx         # 할 일 목록
│   └── TodoItem.jsx         # 할 일 항목
├── context/
│   └── TodoContext.jsx      # 전역 상태 관리
└── utils/
    └── storage.js           # LocalStorage 유틸

시작하기

# 의존성 설치
npm install

# 개발 서버 실행
npm run dev

@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와 Vite를 사용하여 완전한 기능을 갖춘 투두(Todo) 애플리케이션을 구축합니다. 사용자들은 할 일을 효율적으로 관리할 수 있으며, 모든 데이터는 LocalStorage를 통해 영구적으로 저장됩니다. 이 애플리케이션은 할 일의 추가, 삭제, 수정, 완료 상태 토글, 전체 완료/해제, 그리고 남은 할 일 개수 표시 등 핵심적인 투두 기능을 제공합니다.

Highlights

  • 할 일 추가 / 삭제 / 수정: 사용자가 할 일을 추가하고, 기존 할 일을 삭제하거나 내용을 수정할 수 있는 기능이 구현되었습니다.
  • 완료 체크 및 취소선 표시: 각 할 일 항목에 완료 여부를 체크할 수 있는 기능과 완료된 할 일에 취소선이 표시되는 기능이 추가되었습니다.
  • 전체 완료 / 전체 해제: 모든 할 일을 한 번에 완료 처리하거나 완료 상태를 해제할 수 있는 기능이 추가되었습니다.
  • 남은 할 일 개수 표시: 아직 완료되지 않은 할 일의 개수를 실시간으로 표시하는 기능이 추가되었습니다.
  • LocalStorage를 이용한 데이터 영속성: 할 일 데이터가 LocalStorage에 저장되어 브라우저를 닫았다 다시 열어도 데이터가 유지됩니다.

🧠 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

This pull request introduces a new React Todo application, setting up the project with Vite, Tailwind CSS, ESLint, and Prettier. Key changes include adding a comprehensive .gitignore, configuring Prettier for code formatting, updating the README.md with project details and usage instructions, and setting up ESLint with React hooks and refresh plugins. The core application logic involves TodoContext for state management (add, remove, toggle, update todos, and track active count), TodoWriteForm for adding new tasks, TodoList to display tasks, and TodoItem for individual task actions. LocalStorage is used for data persistence. The review comments suggest several improvements: addressing a potential bug in TodoContext where useRef for lastId might not update correctly, recommending useState or dynamic calculation instead; improving user experience by replacing alert calls with integrated UI feedback for form validations; correcting multiple typos of seletedId to selectedId across TodoItem and TodoContext; moving development-only dependencies (eslint-config-prettier, postcss, prettier) from dependencies to devDependencies in package.json; removing redundant setText('') calls in TodoWriteForm after form.reset(); refining the ESLint no-unused-vars rule to be more specific than ignoring all uppercase variables; and adding try-catch blocks to JSON.parse() in storage.js to handle potential parsing errors gracefully.

{ id: 1, text: '운동하기', checked: true },
])

const lastId = useRef(todos.length > 0 ? Math.max(...todos.map(todo => todo.id)) + 1 : 1)

Choose a reason for hiding this comment

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

high

lastIduseRef로 관리하는 방식은 todos 배열이 초기화된 이후에 변경될 경우 lastId.current가 업데이트되지 않는 문제를 발생시킬 수 있습니다. useRef는 컴포넌트의 생명주기 동안 한 번만 초기화됩니다. todos에 항목이 추가되거나 삭제될 때 lastId가 항상 최신 값을 반영하도록 useState를 사용하거나 addTodo 함수 내에서 동적으로 계산하는 것이 더 안전합니다.

    const [nextId, setNextId] = useState(todos.length > 0 ? Math.max(...todos.map(todo => todo.id)) + 1 : 1)

    useEffect(() => {
        if (todos.length > 0) {
            setNextId(Math.max(...todos.map(todo => todo.id)) + 1)
        } else {
            setNextId(1)
        }
    }, [todos])

e.preventDefault()
const form = e.target

if (form.todo.value.trim().length == 0) {

Choose a reason for hiding this comment

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

medium

사용자에게 피드백을 제공하기 위해 alert를 사용하는 것은 현대 웹 애플리케이션에서 권장되지 않습니다. alert는 UI를 차단하고 스타일을 지정할 수 없기 때문에 사용자 경험을 저해할 수 있습니다. 대신, 입력 필드 옆에 오류 메시지를 표시하는 등 UI에 통합된 피드백 메커니즘을 사용하는 것이 좋습니다.

Comment on lines +15 to +17
"eslint-config-prettier": "^10.1.8",
"postcss": "^8.5.8",
"prettier": "^3.8.1",

Choose a reason for hiding this comment

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

medium

eslint-config-prettier, postcss, prettier는 개발 환경에서만 사용되는 도구이므로 dependencies가 아닌 devDependencies로 이동하는 것이 적절합니다. 이는 프로젝트의 실제 런타임 의존성을 명확히 하고 번들 크기를 최적화하는 데 도움이 됩니다.

    "dependencies": {
        "@tailwindcss/postcss": "^4.2.1",
        "react": "^19.2.4",
        "react-dom": "^19.2.4",
        "tailwindcss": "^4.2.1"
    },
    "devDependencies": {
        "@eslint/js": "^9.39.4",
        "@types/react": "^19.2.14",
        "@types/react-dom": "^19.2.3",
        "@vitejs/plugin-react": "^6.0.0",
        "eslint": "^9.39.4",
        "eslint-config-prettier": "^10.1.8",
        "eslint-plugin-react-hooks": "^7.0.1",
        "eslint-plugin-react-refresh": "^0.5.2",
        "globals": "^17.4.0",
        "postcss": "^8.5.8",
        "prettier": "^3.8.1",
        "vite": "^8.0.0"
    }


const handleSave = () => {
if (editText.trim().length === 0) {
alert('할 일을 입력해주세요.')

Choose a reason for hiding this comment

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

medium

사용자에게 피드백을 제공하기 위해 alert를 사용하는 것은 현대 웹 애플리케이션에서 권장되지 않습니다. alert는 UI를 차단하고 스타일을 지정할 수 없기 때문에 사용자 경험을 저해할 수 있습니다. 대신, 입력 필드 옆에 오류 메시지를 표시하는 등 UI에 통합된 피드백 메커니즘을 사용하는 것이 좋습니다.

const handleCancel = () => {
setEditText(todo.text)
setIsEditing(false)
}

Choose a reason for hiding this comment

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

medium

seletedId는 오타입니다. selectedId로 수정해야 합니다. 이 오타는 코드 전체에 걸쳐 여러 번 나타납니다.

    const removeTodo = (selectedId) => {

},
},
rules: {
'no-unused-vars': ['error', { varsIgnorePattern: '^[A-Z_]' }],

Choose a reason for hiding this comment

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

medium

varsIgnorePattern: '^[A-Z_]'는 대문자로 시작하거나 밑줄로 시작하는 모든 변수를 무시하므로, 의도치 않게 사용되지 않는 React 컴포넌트나 중요한 변수를 놓칠 수 있습니다. 특정 유형의 변수만 무시하도록 패턴을 더 구체적으로 지정하는 것이 좋습니다.

lastId.current++
}

const removeTodo = (seletedId) => {

Choose a reason for hiding this comment

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

medium

seletedId는 오타입니다. selectedId로 수정해야 합니다. 이 오타는 코드 전체에 걸쳐 여러 번 나타납니다.

    const removeTodo = (selectedId) => {

setTodos(filterTodos)
}

const toggleTodo = (seletedId) => {

Choose a reason for hiding this comment

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

medium

seletedId는 오타입니다. selectedId로 수정해야 합니다.

    const toggleTodo = (selectedId) => {

setTodos(updateTodos)
}

const updateTodo = (seletedId, newText) => {

Choose a reason for hiding this comment

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

medium

seletedId는 오타입니다. selectedId로 수정해야 합니다.

    const updateTodo = (selectedId, newText) => {

@@ -0,0 +1,8 @@
export const getStorage = (key) => {
const data = localStorage.getItem(key)
return data ? JSON.parse(data) : null

Choose a reason for hiding this comment

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

medium

JSON.parse()는 유효하지 않은 JSON 문자열을 파싱하려고 할 때 오류를 발생시킬 수 있습니다. try-catch 블록으로 감싸서 잠재적인 파싱 오류를 안전하게 처리하는 것이 좋습니다. 이렇게 하면 저장된 데이터가 손상되었을 때 앱이 충돌하는 것을 방지할 수 있습니다.

    try {
        return data ? JSON.parse(data) : null
    } catch (error) {
        console.error("Failed to parse data from localStorage:", error)
        return null
    }

@HeungJunBag HeungJunBag changed the title React Todo App [AIBE6/1팀/박흥준] TODO APP 만들기 완료 Mar 19, 2026
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.

1 participant