-
Notifications
You must be signed in to change notification settings - Fork 7
[2주차] 정시원 미션 제출합니다 #1
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,20 +1,72 @@ | ||||||||||||||||||||||||||||||||
| import React from "react"; | ||||||||||||||||||||||||||||||||
| import React, { useState } from "react"; | ||||||||||||||||||||||||||||||||
| import styled from "styled-components"; | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| export default function TodoInput() { | ||||||||||||||||||||||||||||||||
| return ( | ||||||||||||||||||||||||||||||||
| <Wrapper> | ||||||||||||||||||||||||||||||||
| 리액트-투두 | ||||||||||||||||||||||||||||||||
| <br /> | ||||||||||||||||||||||||||||||||
| 시간을 입력하는 칸 | ||||||||||||||||||||||||||||||||
| <br /> | ||||||||||||||||||||||||||||||||
| Todo를 입력하는 칸 | ||||||||||||||||||||||||||||||||
| </Wrapper> | ||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||
| export default function TodoInput({ addTodo }) { | ||||||||||||||||||||||||||||||||
| const [thisTodo, setThisTodo] = useState({ | ||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| const inputChangeHandler = (el) => { | ||||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||
| const { name, value } = el.target; | ||||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. destructuring 잘 써주셨네요 👍 |
||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| if (name === 'dueDate') { | ||||||||||||||||||||||||||||||||
| if (value.length > 8) { | ||||||||||||||||||||||||||||||||
| el.target.value = value.slice(0, 8); | ||||||||||||||||||||||||||||||||
| return; | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| setThisTodo({ | ||||||||||||||||||||||||||||||||
| ...thisTodo, | ||||||||||||||||||||||||||||||||
| [name]: value | ||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||
|
Comment on lines
+11
to
+21
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
이렇게 리팩토링할 수 있습니다! |
||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| return ( | ||||||||||||||||||||||||||||||||
| <Wrapper> | ||||||||||||||||||||||||||||||||
| <TimeInput> | ||||||||||||||||||||||||||||||||
| <p style={{"fontSize":"1.5rem","padding":"0px","margin":"0px"}}>시간</p> | ||||||||||||||||||||||||||||||||
| <input style={{ "width": "80%", "borderWidth": "1px", "borderStyle": "solid", "borderColor": "rgb(97, 97, 97)", "borderImage": "initial", "padding": "0.5rem 0.8rem" }} name="dueDate" onChange={inputChangeHandler} type="number" placeholder="날짜를 입력하세요 (ex.20200404)"></input> | ||||||||||||||||||||||||||||||||
|
Comment on lines
+26
to
+28
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. styled-componet를 사용해주세요 ㅎ ㅠ |
||||||||||||||||||||||||||||||||
| </TimeInput> | ||||||||||||||||||||||||||||||||
| <ContentInput> | ||||||||||||||||||||||||||||||||
| <p style={{"fontSize":"1.5rem","padding":"0px","margin":"0px"}}>TODO</p> | ||||||||||||||||||||||||||||||||
| <textarea style={{"width":"80%","height":"30vh","resize":"none","borderWidth":"1px","borderStyle":"solid","borderColor":"rgb(97, 97, 97)","borderImage":"initial","padding":"0.5rem 0.8rem"}} name="content" onChange={inputChangeHandler} placeholder="할 일을 입력하세요"></textarea> | ||||||||||||||||||||||||||||||||
| </ContentInput> | ||||||||||||||||||||||||||||||||
| <button style={{"color":"white","backgroundColor":"rgb(97, 97, 97)","fontSize":"1.5rem","outline":"none","borderWidth":"initial","borderStyle":"none","borderColor":"initial","borderImage":"initial","padding":"0.5rem 1rem","borderRadius":"0.3rem"}} onClick={(() => { | ||||||||||||||||||||||||||||||||
| addTodo(thisTodo); | ||||||||||||||||||||||||||||||||
| })}>등록</button> | ||||||||||||||||||||||||||||||||
| </Wrapper> | ||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| const TimeInput = styled.div` | ||||||||||||||||||||||||||||||||
| width: 100%; | ||||||||||||||||||||||||||||||||
| display: flex; | ||||||||||||||||||||||||||||||||
| flex-direction: row; | ||||||||||||||||||||||||||||||||
| -webkit-box-pack: justify; | ||||||||||||||||||||||||||||||||
| justify-content: space-between; | ||||||||||||||||||||||||||||||||
| align-items: flex-start; | ||||||||||||||||||||||||||||||||
| margin-bottom: 3rem;` | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| const ContentInput = styled.div` | ||||||||||||||||||||||||||||||||
| width: 100%; | ||||||||||||||||||||||||||||||||
| display: flex; | ||||||||||||||||||||||||||||||||
| flex-direction: row; | ||||||||||||||||||||||||||||||||
| -webkit-box-pack: justify; | ||||||||||||||||||||||||||||||||
| justify-content: space-between; | ||||||||||||||||||||||||||||||||
| align-items: flex-start; | ||||||||||||||||||||||||||||||||
| margin-bottom: 3rem;` | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| const Wrapper = styled.div` | ||||||||||||||||||||||||||||||||
| border: solid 1px; | ||||||||||||||||||||||||||||||||
| font-size: 18px; | ||||||||||||||||||||||||||||||||
| flex: 1; | ||||||||||||||||||||||||||||||||
| `; | ||||||||||||||||||||||||||||||||
| width: 100%; | ||||||||||||||||||||||||||||||||
| display: flex; | ||||||||||||||||||||||||||||||||
| flex-direction: column; | ||||||||||||||||||||||||||||||||
| -webkit-box-align: center; | ||||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||
| align-items: center; | ||||||||||||||||||||||||||||||||
| height: 37rem; | ||||||||||||||||||||||||||||||||
| flex: 1 1 0%; | ||||||||||||||||||||||||||||||||
| border-width: 1px; | ||||||||||||||||||||||||||||||||
| border-style: solid; | ||||||||||||||||||||||||||||||||
| border-color: black; | ||||||||||||||||||||||||||||||||
| border-image: initial; | ||||||||||||||||||||||||||||||||
|
Comment on lines
+67
to
+70
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||
| padding: 1rem 2rem; | ||||||||||||||||||||||||||||||||
| `; | ||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,11 +1,34 @@ | ||
| import React from "react"; | ||
| import styled from "styled-components"; | ||
|
|
||
| export default function TodoItem() { | ||
| return <Wrapper>Todo</Wrapper>; | ||
| function TodoItem({ id, content, dueDate, completeTodo }) { | ||
| return <Wrapper> | ||
| <p style={{"fontSize":"1.5rem","display":"flex","flexDirection":"column","padding":"0px","margin":"0px"}}>{content}</p> | ||
| <p style={{"fontSize":"1.5rem","display":"flex","flexDirection":"column","padding":"0px","margin":"0px"}}>{dueDate} | ||
| <button style={{"color":"white","backgroundColor":"rgb(97, 97, 97)","fontSize":"1.5rem","outline":"none","borderWidth":"initial","borderStyle":"none","borderColor":"initial","borderImage":"initial","padding":"0.5rem 1rem","borderRadius":"0.3rem"}} onClick={(() => { completeTodo(id) })}> | ||
| 완료 | ||
| </button> | ||
| </p> | ||
| </Wrapper>; | ||
| } | ||
|
|
||
| const Wrapper = styled.div` | ||
| font-size: 18px; | ||
| border: solid 1px; | ||
| width: 100%; | ||
| display: flex; | ||
| flex-direction: row; | ||
| -webkit-box-pack: justify; | ||
| justify-content: space-between; | ||
| align-items: flex-start; | ||
| margin-bottom: 3rem; | ||
| padding: 1rem 2rem; | ||
| border-width: 1px; | ||
| border-style: solid; | ||
| border-color: black; | ||
| border-image: initial; | ||
| `; | ||
|
|
||
| const areEqual = (prevProps, nextProps) => { | ||
| return prevProps.id === nextProps.id; | ||
| } | ||
|
|
||
| export default React.memo(TodoItem, areEqual); | ||
|
Comment on lines
+30
to
+34
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 잘 적용해주셨네요!!! 좋습니다 ㅎ 👍 |
||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -3,17 +3,17 @@ import styled from "styled-components"; | |||||
|
|
||||||
| import TodoItem from "./todo-item"; | ||||||
|
|
||||||
| export default function TodoList() { | ||||||
| return ( | ||||||
| <Wrapper> | ||||||
| Todo list가 들어가는 자리입니다! | ||||||
| <TodoItem /> | ||||||
| </Wrapper> | ||||||
| ); | ||||||
| export default function TodoList({ todos, completeTodo }) { | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. TodoList에도 React.memo를 적용해보세요~ |
||||||
| return ( | ||||||
| <Wrapper> | ||||||
| {todos.sort((todo1, todo2) => { | ||||||
| return todo1.dueDate < todo2.dueDate ? -1 : todo1.dueDate > todo2.dueDate ? 1 : 0; | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. sort의 compare 함수는 양수, 0, 음수여부만 판단하기 때문에
Suggested change
라고만 해주셔도 됩니다 ㅎ |
||||||
| }).map((todo) => (todo.isComplete ? null : <TodoItem key={todo.id} {...todo} completeTodo={completeTodo} />))} | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. map함수에서 3항연산자를 사용해 선택적으로 return 하는 것 보다 filter함수를 쓰는게 더 좋을 것 같아요! |
||||||
| </Wrapper> | ||||||
| ); | ||||||
| } | ||||||
|
|
||||||
| const Wrapper = styled.div` | ||||||
| border: solid 1px; | ||||||
| font-size: 18px; | ||||||
| flex: 1; | ||||||
| font-size: 18px; | ||||||
| flex: 1 1 0%; | ||||||
| `; | ||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,30 +1,78 @@ | ||
| import React from "react"; | ||
| import React, { useState } from "react"; | ||
|
|
||
| import TodoInput from "../components/todo-input"; | ||
| import TodoList from "../components/todo-list"; | ||
|
|
||
| import styled from "styled-components"; | ||
|
|
||
| export default function Home() { | ||
| const [todos, setTodos] = useState([ | ||
| ]) | ||
|
|
||
| const [counter, setCounter] = useState(1) // todo 샘플 지울때 0으로 바꾸기. | ||
|
|
||
| // todo 추가하기 | ||
| const addTodo = ({ content, dueDate }) => { | ||
| // check whether every input is filled | ||
| if ((content === undefined) || (dueDate === undefined)) { | ||
| alert('모든 항목을 입력해주세요!'); | ||
| return; | ||
| } | ||
|
|
||
| // check whether dueDate is valid | ||
| const dateRegExp = /^\d{8}$/; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 정규표현식을 사용해주신 점이 정말 멋있는 것 같아요 |
||
| if (!dateRegExp.exec(dueDate)) { | ||
| alert('날짜를 올바른 형식으로 입력해주세요!'); | ||
| return; | ||
| } | ||
|
|
||
| // add todo to todos | ||
| // increment counter | ||
| setCounter(counter + 1); | ||
| setTodos([ | ||
| ...todos, | ||
| { id: counter, content, dueDate, isComplete: false } | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. isComplete 사용하신 것 참신하네요 👍 |
||
| ]) | ||
|
|
||
| alert('입력 완료!') | ||
| } | ||
|
|
||
| // todo 완료하기 | ||
| const completeTodo = (id) => { | ||
| setTodos( | ||
| todos.map((todo) => todo.id === id ? { ...todo, isComplete: true } : todo) | ||
| ) | ||
| } | ||
|
|
||
| return ( | ||
| <Wrapper> | ||
| <Title>리액트-투두</Title> | ||
| <Contents> | ||
| <TodoInput /> | ||
| <TodoList /> | ||
| <TodoInput addTodo={addTodo} /> | ||
| <div style={{flex:0.3}}></div> | ||
| <TodoList completeTodo={completeTodo} todos={todos} /> | ||
| </Contents> | ||
| <div style={{position:'fixed', right:0, top:0, padding: '1px', fontSize:'9px', backgroundColor:'grey'}}>CEOS 11기 정시원</div> | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. style을 inline으로 다는 것은 별로 좋은 습관은 아니랍니다 ㅎㅎ |
||
| </Wrapper> | ||
| ); | ||
| } | ||
|
|
||
| const Wrapper = styled.div` | ||
| height: 100vh; | ||
| min-height: 100vh; | ||
| background-color: rgb(155, 197, 195); | ||
| padding: 4rem 5rem; | ||
| `; | ||
|
|
||
| const Contents = styled.div` | ||
| border: solid 1px black; | ||
| display: flex; | ||
| flex-direction: row; | ||
| justify-content: space-between; | ||
| padding: 10px 20px; | ||
| margin: 20px 10px; | ||
| display: flex; | ||
| flex-direction: row; | ||
| -webkit-box-pack: justify; | ||
| justify-content: space-between; | ||
| `; | ||
|
|
||
| const Title = styled.p` | ||
| font-size: 3rem; | ||
| font-weight: 600; | ||
| padding: 0px; | ||
| margin: 0px 0px 3rem; | ||
| ` | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
현재 입력중인 todo라는 역할을 잘 설명하지 못 하는 것 같아요!