Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

조민영 과제 제출 합니다 #4

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
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 조민영/vite-project/.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?
50 changes: 50 additions & 0 deletions 조민영/vite-project/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# React + TypeScript + Vite

This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.

Currently, two official plugins are available:

- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh

## Expanding the ESLint configuration

If you are developing a production application, we recommend updating the configuration to enable type aware lint rules:

- Configure the top-level `parserOptions` property like this:

```js
export default tseslint.config({
languageOptions: {
// other options...
parserOptions: {
project: ['./tsconfig.node.json', './tsconfig.app.json'],
tsconfigRootDir: import.meta.dirname,
},
},
})
```

- Replace `tseslint.configs.recommended` to `tseslint.configs.recommendedTypeChecked` or `tseslint.configs.strictTypeChecked`
- Optionally add `...tseslint.configs.stylisticTypeChecked`
- Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and update the config:

```js
// eslint.config.js
import react from 'eslint-plugin-react'

export default tseslint.config({
// Set the react version
settings: { react: { version: '18.3' } },
plugins: {
// Add the react plugin
react,
},
rules: {
// other rules...
// Enable its recommended rules
...react.configs.recommended.rules,
...react.configs['jsx-runtime'].rules,
},
})
```
28 changes: 28 additions & 0 deletions 조민영/vite-project/eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import js from '@eslint/js'
import globals from 'globals'
import reactHooks from 'eslint-plugin-react-hooks'
import reactRefresh from 'eslint-plugin-react-refresh'
import tseslint from 'typescript-eslint'

export default tseslint.config(
{ ignores: ['dist'] },
{
extends: [js.configs.recommended, ...tseslint.configs.recommended],
files: ['**/*.{ts,tsx}'],
languageOptions: {
ecmaVersion: 2020,
globals: globals.browser,
},
plugins: {
'react-hooks': reactHooks,
'react-refresh': reactRefresh,
},
rules: {
...reactHooks.configs.recommended.rules,
'react-refresh/only-export-components': [
'warn',
{ allowConstantExport: true },
],
},
},
)
13 changes: 13 additions & 0 deletions 조민영/vite-project/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!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 + TS</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
29 changes: 29 additions & 0 deletions 조민영/vite-project/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"name": "vite-project",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc -b && vite build",
"lint": "eslint .",
"preview": "vite preview"
},
"dependencies": {
"react": "^18.3.1",
"react-dom": "^18.3.1"
},
"devDependencies": {
"@eslint/js": "^9.13.0",
"@types/react": "^18.3.12",
"@types/react-dom": "^18.3.1",
"@vitejs/plugin-react-swc": "^3.5.0",
"eslint": "^9.13.0",
"eslint-plugin-react-hooks": "^5.0.0",
"eslint-plugin-react-refresh": "^0.4.14",
"globals": "^15.11.0",
"typescript": "~5.6.2",
"typescript-eslint": "^8.11.0",
"vite": "^5.4.10"
}
}
1 change: 1 addition & 0 deletions 조민영/vite-project/public/vite.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 7 additions & 0 deletions 조민영/vite-project/src/App.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#root {
max-width: 1280px;
margin: 0 auto;
padding: 2rem;
text-align: center;
}

10 changes: 10 additions & 0 deletions 조민영/vite-project/src/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import TodoTable from "./TodoTable";
import "./App.css";

function App() {
return(
<TodoTable/>
);
}

export default App;
80 changes: 80 additions & 0 deletions 조민영/vite-project/src/Todo.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
.container{
width: 400px;
height:600px;
box-shadow: 0px 2px 5px #c3c3c3
}
.top{
display:flex;
align-items: center;
justify-content: center;
height:50px;
font-size:25px;
font-weight: 540;
color:rgba(102, 140, 255);
border-bottom: 2px solid #eaeaea;

}

.mid{
padding-left: 10px;
height: 500px;
font-size:14px;
color:#686767;
border-bottom: 2px solid #eaeaea;
}

.place{
display:flex;
align-items: flex-start;
border:1px solid white;
width:300px;
height:30px;

}

.bottom{
display:flex;
align-items: center;
justify-content: space-around;
height:50px;
font-size: 12px;
color:rgba(102, 140, 255);
}

.bottom button{
font-size: 12px;
color:rgba(102, 140, 255);
background-color: white;
}


table{
display:flex;
align-items:flex-start;
flex-direction: column;
color:rgba(102, 140, 255);
}

.d{
font-size: 14px;
color:rgba(102, 140, 255);
margin-left: 80px;
}

input[type="checkbox"] {
width: 1rem;
height: 1rem;
border-radius: 50%;
border: 1px solid #c3c3c3;
appearance: none;
cursor: pointer;
transition: background 0.2s;
}

input[type="checkbox"]:checked {
background:rgba(102, 140, 255);
border: none;
}



114 changes: 114 additions & 0 deletions 조민영/vite-project/src/TodoTable.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
/* eslint-disable @typescript-eslint/no-unused-expressions */
import "./Todo.css";
import { useState } from "react";

//1. 인풋으로 입력한 내용이 todoText로 들어가야함--함수 연결해서 바뀐 값을 배열에 추가하fail.useState하기
//2. 속성과 체크박스 연결시키기--useState
//3. sum--useState그리고 어케 연결?
//4. 체크박스 모양 바꾸기--이건 이지
//5. 삭제 버튼을 계속 옆에 띄우는 법?--걍 넣어벌임
//6. 컴포넌트를 어떻게 쪼개지?--쪼개지말자..
Comment on lines +5 to +10
Copy link
Contributor

Choose a reason for hiding this comment

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

과제를 제출할 땐 불필요한 주석은 제거해주세요.

let indexT = 1;
Copy link
Contributor

Choose a reason for hiding this comment

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

리액트에서는 관리해야하는 값에 대해 state라는 개념을 사용합니다.
리액트 상태관리에 대해 공부해보세요!
노션 web자료에 리액트 공식문서에 들어가셔서 State: 컴포넌트의 기억 저장소 글을 읽어보시길 추천드려요.

function TodoTable() {
type Todos = { Id: number; todoText: string; isDone: boolean };
const [Todo, setTodo] = useState<Todos[]>([]);
const [todoText, setTodoText] = useState("");
const tdList = Todo.map((Todo) => (
<tr key={Todo.Id}>
<td>
<label htmlFor="chBox">
<input
type="checkbox"
onChange={() => isitDone(Todo.Id)}
checked={Todo.isDone}
value={Todo.Id}
/>
</label>
</td>
<td>
<span id="span">{Todo.todoText}</span>
</td>
<td>
<button onClick={() => decrease(Todo.Id)} value={Todo.Id} className="d">
삭제
</button>
</td>
</tr>
));
Comment on lines +17 to +37
Copy link
Contributor

Choose a reason for hiding this comment

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

table로 작성하신 이유가 뭔지 알려주세요!


const [sum, setSum] = useState(0);
Copy link
Contributor

Choose a reason for hiding this comment

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

훅들은 최상위에 작성하는 것이 규칙입니다.

const increase = () => {
setSum(sum + 1);
};
const decrease = (id) => {
d(id);
Copy link
Contributor

Choose a reason for hiding this comment

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

함수 이름을 의미있게 작성해보는 습관을 가져볼까요?
d함수가 뭔지 다른 사람이 코드를 봤을 때 알기 어려울 것 같아요.

setSum(sum - 1);
if (sum == 0) {
setSum(0);
}
};
const d = (id) => {
setTodo(Todo.filter((t) => t.Id !== id));
};
const inputTodo = () => {
if (todoText == "") {
alert("등록할 일정을 입력해주세요!");
} else {
const newTodo: Todos = {
Id: indexT,
todoText: todoText,
isDone: false,
};
setTodo([...Todo, newTodo]);
increase();
indexT += 1;
setTodoText("");
Comment on lines +57 to +65
Copy link
Contributor

Choose a reason for hiding this comment

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

id는 "관리해야하는 값"에 속하기 때문에 state로 관리를 하셔야 합니다.
또한 indetT와 Increase는 무슨 역할인가요? sum state는 무엇을 관리하는 state인가요?

}
};
Comment on lines +54 to +67
Copy link
Contributor

Choose a reason for hiding this comment

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

공백검사가 되지 않네요 또한 early return에 대해 알아보시고 early return과 if else의 차이는 무엇일지 공부해보세요!


const isitDone = (id) => {
setTodo(
Todo.map((todo) =>
todo.Id === id ? { ...todo, isDone: !todo.isDone } : todo
)
);

const filterSum = Todo.filter((todo) => todo.isDone == true);
setSum(filterSum.length);
Todo.map((todo) => (todo.isDone == false ? strikeLine() : nonStrike()));
};

const strikeLine = () => {
const c = document.getElementById("span");
c.style.textDecoration = "line-through";
};

const nonStrike = () => {
const c = document.getElementById("span");
c.style.textDecoration = "";
};
Comment on lines +76 to +89
Copy link
Contributor

Choose a reason for hiding this comment

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

css를 적용하기 위해 함수를 작성하신 것 같은데 react에서는 직접 dom을 조작해서 스타일을 하지 않습니다. 실제로 적용도 되지 않는 것 같아보이고요. 어떤 상황에 스타일을 적용해야한다면 className에 특정 조건에 이 스타일을 적용해라라는 삼항연산자를 사용할 수 있어요!

return (
<div className="container">
<div className="top">
<p>TodoList</p>
</div>
<div className="mid">
<input
className="place"
type="text"
value={todoText}
onChange={(t) => setTodoText(t.target.value)}
Copy link
Contributor

Choose a reason for hiding this comment

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

여기서 t가 무엇인가요? t가 하는 역할이 뭐고 이렇게 작성하신 이유를 알려주세요.

name="todoText"
placeholder="오늘의 할 일을 추가해보세요!"
/>
<table>{tdList}</table>
</div>
<div className="bottom">
<p>오늘의 할 일 {sum}</p>
<button onClick={inputTodo}>추가하기</button>
</div>
</div>
);
}

export default TodoTable;
1 change: 1 addition & 0 deletions 조민영/vite-project/src/assets/react.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading