Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
*.local

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
7 changes: 7 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"printWidth": 120,
"tabWidth": 4,
"singleQuote": true,
"trailingComma": "all",
"semi": false
}
8 changes: 8 additions & 0 deletions .vite/deps/_metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"hash": "49fb6638",
"configHash": "00332054",
"lockfileHash": "67ab5898",
"browserHash": "0a4b5a5c",
"optimized": {},
"chunks": {}
}
3 changes: 3 additions & 0 deletions .vite/deps/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"type": "module"
}
65 changes: 64 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,64 @@
# 리액트 투두 앱 만들기 미션 레포
# 리액트 투두 앱 만들기 미션

## 🎯 프로젝트 개요

이 과제는 **React와 Vite**를 사용해 간단한 Todo List를 구현하는 프로젝트입니다.

컴포넌트 구조와 상태 관리를 이해하고, **localStorage를 활용한 데이터 유지** 기능을 구현합니다.

**할 일을 입력하면 목록에 추가되고, 삭제할 수 있으며, localStorage에 저장되어 새로고침해도 유지**됩니다.

| 기능 | 설명 |
| ----------------- | -------------------------------------------------------- |
| 할 일 추가 | 텍스트 입력 후 버튼 클릭 시 리스트에 항목 추가 |
| 할 일 삭제 | 항목의 삭제 버튼 클릭 시 해당 항목 제거 |
| 완료 체크 | 체크박스를 클릭하면 완료 여부 표시 (스타일 변화 포함) |
| localStorage 저장 | 추가/삭제/체크 시 변경된 todo 상태를 localStorage에 저장 |
| 초기 로드 | 앱 실행 시 localStorage에서 데이터를 불러와 렌더링 |

### ✅ 할 일 데이터 구조 예시

```python
{id: '고유 ID',
value: '할 일 내용',
completed: false // 체크 여부}
```


### ⚛️ 주요 컴포넌트 구조 예시

```python
src/
├─ components/
│ ├─ TodoItem.jsx
│ └─ TodoList.jsx
├─ App.jsx
├─ main.jsx
├─ hooks/
│ └─ useTodos.js ← 상태 및 로직 커스텀 훅
└─ utils/
└─ storage.js ← getStorage, setStorage
```

### 🧠 스크린샷

<img width="900" alt="image1" src="https://github.com/user-attachments/assets/1a1fb12f-c16b-4ee4-8cf6-3f761001033c" />
<img width="900" alt="image2" src="https://github.com/user-attachments/assets/090975ef-755c-491e-b9aa-83cfc3c4b8e4" />

### 🎨 TailwindCSS를 이용한 스타일 요소 구현

cdn방식


### 💾 localStorage 연동 방식

useEffect()를 사용해 앱 최초 로딩 시 localStorage에서 todos 불러오기
todos 배열이 변경될 때마다 localStorage에 자동 저장되도록 설정

```jsp
useEffect(() => {
setStorage('todos', todos);
}, [todos]);
```

29 changes: 29 additions & 0 deletions eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import js from '@eslint/js'
import globals from 'globals'
import reactHooks from 'eslint-plugin-react-hooks'
import reactRefresh from 'eslint-plugin-react-refresh'
import { defineConfig, globalIgnores } from 'eslint/config'

export default defineConfig([
globalIgnores(['dist']),
{
files: ['**/*.{js,jsx}'],
extends: [
js.configs.recommended,
reactHooks.configs['recommended-latest'],
reactRefresh.configs.vite,
],
languageOptions: {
ecmaVersion: 2020,
globals: globals.browser,
parserOptions: {
ecmaVersion: 'latest',
ecmaFeatures: { jsx: true },
sourceType: 'module',
},
},
rules: {
'no-unused-vars': ['error', { varsIgnorePattern: '^[A-Z_]' }],
},
},
])
14 changes: 14 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + React</title>
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.jsx"></script>
</body>
</html>
Loading