-
Notifications
You must be signed in to change notification settings - Fork 0
Code review hyungjun #2
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
base: main
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
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,14 @@ | ||
| .App { | ||
| } | ||
| @tailwind base; | ||
| @tailwind components; | ||
| @tailwind utilities; | ||
|
|
||
| @layer base { | ||
| h1 { | ||
| @apply text-2xl font-semibold | ||
| ; | ||
| } | ||
| h2 { | ||
| @apply text-xl; | ||
| } | ||
|
|
||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,10 +1,71 @@ | ||
|
|
||
| import React, {useState, useCallback} from "react"; | ||
| import { v4 as uuidv4 } from 'uuid'; | ||
| import './App.css'; | ||
| import Form from "./components/Form"; | ||
| import List from "./components/List"; | ||
| import Lists from "./components/Lists" | ||
| //만약 localStorage에 key(Diary)로 저장된 value가 있을 경우 그것을 가져오도록 | ||
| //텍스트 형태로 저장되어있으므로 JSON.parse()로 바꿔줌 | ||
| const initiaMyDiary = localStorage.getItem("Diary") ? JSON.parse(localStorage.getItem("Diary")):[]; | ||
|
|
||
| function App() { | ||
| console.log('App Component') | ||
| const[DiaryData, setDiaryData] = useState(initiaMyDiary); | ||
| // const[DiaryData, setDiaryData] = useState([]); | ||
| const[value, setValue] = useState(""); | ||
|
|
||
| //List에서 handleClick를 사용하기 때문에 리랜더링발생 --> 성능저하 | ||
| //useCallback() : DiaryData가 변하지 않는다면 함수는 새로 생성되지 않음(새로 생성되지 않으므로 메모리에 새로 할당되지 않고 동일 참조값을 사용) | ||
| const handleClick = useCallback((id) => { | ||
| let newDiaryData = DiaryData.filter((data) => data.id !== id); //id가 같다면 삭제하도록 | ||
| setDiaryData(newDiaryData); | ||
| console.log('newDiaryData',newDiaryData); | ||
| //setDiaryData를 이용해서 DiaryData를 바꿔줄 떄, localStorage도 같이 바꿔주기 | ||
| //객체나 배열을 저장해줄시에는 JSON.stringify를 이용해서 텍스트로 변환해준 후 저장 | ||
| //setItem('key', 'value') -> value가 객체일때 Object로 저장되므로 아래와 같이 JSON.stringify()를 사용해주기 | ||
| localStorage.setItem('Diary', JSON.stringify(newDiaryData)); | ||
| }, | ||
| [DiaryData] | ||
| ) | ||
| // const handleClick = (id)=>{ | ||
| // console.log("handleClick", id); | ||
| // let newDiaryData = DiaryData.filter((data) => data.id !== id); | ||
| // setDiaryData(newDiaryData); | ||
| // console.log('newDiaryData', newDiaryData); | ||
| // } | ||
|
|
||
| const handleSubmit = (e) =>{ | ||
| e.preventDefault(); | ||
| let date = new Date(); | ||
|
Author
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. 변수명 date, month, day 를 선언하고 초기화 해주셨는데 이중에서 date만 let으로 변수로 선언하고 month,day는 상수로 선언하신 특별한 이유가 있을까요?? 일단 1차적으로 제가 생각했을 때는 date 값이 new Date() 함수를 호출한 값을 반환 받게 되니까 계속 값이 초기화 될수 있어서 let으로 선언하셧나?? 라고 생각을 했는데 그렇게 생각해보면 month와 day도 결국은 값이 바뀌게 되지 않나 싶어서요..! 아니면 제가 변수와 상수의 개념을 약간 잘못 이해하고 있는 것일 수도 있어서 혹시라도 특별한 이유가 있으시다면 알려주시면 감사하겠습니다! |
||
| const month = date.getMonth() +1 ; | ||
| const day = date.getDate(); | ||
| //새로운 일기 | ||
| let newDiary = { | ||
| //날짜 내용 | ||
| id : uuidv4(), | ||
| date : `${month}/${day}`, | ||
| content : value, | ||
| }; | ||
| console.log(newDiary) | ||
| //setter에서 이전 state를 가지고 오기 위해서 인수에 함수를 이용 prev : 이전 데이터, 새로운 데이터 | ||
| setDiaryData(prev => | ||
| [...prev, newDiary] | ||
| ); | ||
| //원래있던 DiaryData를 넣어준 후 newDiary를 넣어줌 | ||
| localStorage.setItem('Diary', JSON.stringify([...DiaryData, newDiary])); | ||
| setValue(""); | ||
| } | ||
|
|
||
|
|
||
| return ( | ||
| <div> | ||
| hello world! 변경변경 shshsh | ||
| <div className="flex items-center justify-center w-screen h-screen bg-white"> | ||
| <div className="w-full p-6 m-4 rounded shadow md:w-3/4 md:max-w-xl lg:w-3/4"> | ||
| <div className = "flex mb-5 justify-center"> | ||
| <h1>한줄 일기</h1> | ||
| </div> | ||
| <Form handleSubmit={handleSubmit} value={value} setValue={setValue}/> | ||
| <Lists handleClick={handleClick} DiaryData={DiaryData} setDiaryData={setDiaryData}/> | ||
| </div> | ||
| </div> | ||
| ); | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| .diary-input{ | ||
| width:250px; | ||
| height: 30px; | ||
| padding:0px; | ||
| } | ||
| .diary-submit{ | ||
| height: 30px; | ||
| margin-left: 10px; | ||
|
|
||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| import React from 'react' | ||
| import './Form.css' | ||
| const Form = ({value, setValue, handleSubmit}) => { | ||
| console.log('Form Component') | ||
| const handleChange = (e) => { | ||
| setValue(e.target.value); | ||
| } | ||
|
|
||
|
|
||
| return ( | ||
| <form onSubmit={handleSubmit} className='flex space-x-4 mb-8'> | ||
| <input | ||
| type="text" | ||
| name="diary" | ||
| placeholder='오늘의 한줄 일기를 작성하세요' | ||
| onChange={handleChange} | ||
| className='w-5/6 h-14 indent-3 bg-rose-100 | ||
| focus:outline-none focus:border-rose-300 border | ||
| border-rose-200 rounded-md text-sm shadow-sm drop-shadow-lg' | ||
| value={value} | ||
| /> | ||
| <input | ||
| type="submit" | ||
| value="입력" | ||
| className='h-14 w-1/6 rounded-full bg-rose-100 hover:bg-rose-200 | ||
| drop-shadow-lg' | ||
| /> | ||
| </form> | ||
| ) | ||
| } | ||
|
|
||
| export default Form |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,89 @@ | ||
| import React,{useState} from 'react' | ||
|
|
||
| const List = ({handleClick, DiaryData, setDiaryData, id, content, date}) => { | ||
| console.log('List Component') | ||
| console.log('DiaryData : ', DiaryData); | ||
| const [isEditing, setIsEditing] = useState(false); | ||
| const [editedContent, setEditedContent] = useState(content); | ||
|
|
||
| //넘기는 인자값이 많을 경우 함수를 생성해서 할수도 있음 | ||
|
Author
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. 오 이렇게 쓰는 방법도 있군요! 함수 내부에서 사용하는 함수들이 많고 인자값이 많으면 이렇게 쓸수도 있겠네요!! 감사합니다!! |
||
| // const hanldeEdit = (data) => {setIsEditing(true); setId(data.id); setEditedContent(data.content); setDate(data.date)} | ||
|
|
||
| const hanldeEdit = (id) => {setIsEditing(true); }; | ||
| //글 수정 | ||
| const handleEditChange = (event) => { | ||
| setEditedContent(event.target.value); | ||
| } | ||
|
|
||
| //수정된 글 저장 | ||
| const handleSubmit = (event) =>{ | ||
| event.preventDefault(); | ||
| let newDiaryData = DiaryData.map(data =>{ | ||
| if(data.id === id){ | ||
| data.content = editedContent; | ||
| } | ||
| return data; | ||
| }) | ||
| setDiaryData(newDiaryData); | ||
| localStorage.setItem('Diary', JSON.stringify(newDiaryData)); | ||
| setIsEditing(false); | ||
| } | ||
|
|
||
|
|
||
| if(isEditing){ | ||
|
Author
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 ... else 문을 사용하셔도 되고 삼항 연산자를 사용해서 코드를 짜시는 분들도 꽤 있는것 같습니다. if(isEditing) ? return(에디팅 상태일때) : return(에디팅상태 아닐때(기본상태) 나중에 이 방법도 사용해 보시면 좋을것 같습니다! |
||
| //수정버튼을 눌렀을 때 | ||
| return ( | ||
| <div className='bg-rose-100 p-1'> | ||
| <div className='flex items-center justify-between w-full mt-2'> | ||
| <div className='flex w-5/6 items-center'> | ||
| <span className='w-1/6 text-center'>{date}</span> | ||
| <form onSubmit={handleSubmit} className='w-5/6'> | ||
| <input | ||
| value={editedContent} | ||
| onChange={handleEditChange} | ||
| className='w-full px-3 py-2 text-gray-500 rounded' | ||
| /> | ||
| </form> | ||
| </div> | ||
| <div className="w-1/6 " > | ||
| <button className="w-1/2" onClick={handleSubmit}> | ||
| 저장 | ||
| </button> | ||
| <button onClick={() => {setIsEditing(false); handleClick(id)}}> | ||
| 삭제 | ||
| </button> | ||
| </div> | ||
| </div> | ||
| </div> | ||
| ) | ||
| }else{ | ||
| return ( | ||
| <div className='bg-rose-100 p-1'> | ||
| <div className='flex items-center justify-between w-full mt-2'> | ||
| <div className='flex w-5/6 items-center'> | ||
| <span className='w-1/6 text-center'>{date}</span> | ||
| {/* <form onSubmit={handleSubmit} className='w-full'> */} | ||
| <div | ||
| className='w-5/6 h-14 text-gray-500 break-words inline-block align-middle ' | ||
| > | ||
| {content} | ||
| </div> | ||
| {/* </form> */} | ||
| </div> | ||
| <div className=" w-1/6" > | ||
| <button className="w-1/2" onClick={() => hanldeEdit(id)}> | ||
| 수정 | ||
| </button> | ||
| <button onClick={() => handleClick(id)}> | ||
| 삭제 | ||
| </button> | ||
| </div> | ||
| </div> | ||
| </div> | ||
|
|
||
|
|
||
|
|
||
| )} | ||
| } | ||
|
|
||
| export default React.memo(List); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| import React from 'react' | ||
| import List from './List' | ||
|
|
||
| const Lists = ({handleClick, DiaryData, setDiaryData}) => { | ||
| console.log("Lists DiaryData : ", DiaryData); | ||
| return ( | ||
| <div> | ||
| <div className='bg-rose-100 p-8'> | ||
| <div className='flex mb-3 '> | ||
| <span className='w-1/6 text-center'>날짜</span><span className='w-5/6 text-left'>내용</span> | ||
| </div> | ||
| <hr className='bg-gray-950 h-px border-0'/> | ||
| { DiaryData.map((data) => ( | ||
| <List | ||
| id={data.id} | ||
| date = {data.date} | ||
| content = {data.content} | ||
| setDiaryData={setDiaryData} | ||
| handleClick={handleClick} | ||
| DiaryData={DiaryData} | ||
| /> | ||
| ))} | ||
| </div> | ||
| </div> | ||
| ) | ||
| } | ||
|
|
||
| export default React.memo(Lists); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,13 +0,0 @@ | ||
| body { | ||
| margin: 0; | ||
| font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', | ||
| 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', | ||
| sans-serif; | ||
| -webkit-font-smoothing: antialiased; | ||
| -moz-osx-font-smoothing: grayscale; | ||
| } | ||
|
|
||
| code { | ||
| font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', | ||
| monospace; | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| /** @type {import('tailwindcss').Config} */ | ||
| module.exports = { | ||
| content: ["./src/**/*.{html,js}"], | ||
| theme: { | ||
| extend: {}, | ||
| }, | ||
| plugins: [], | ||
| } | ||
|
|
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.
경선님은 tailwind css 써보시고 나서 어땠나요??? 제가 생각했을때는 코드를 최초 작성하는 작성자가 작업하기에는 되게 편한 프레임 워크 같은데 만약에 개별 요소에 적용해야될 스타일이 많아질 경우에는 코드 자체의 가독성이 오히려 떨어질수도 있겠다는 생각이 들어서요. 리뷰어의 입장에서는 뭔가 css에 관한 코드는 토글식으로 접을수 있는 기능이 있으면 더 좋지 않을까 라는 생각을 했습니다. 그냥 이것은 개인적으로 써보셨을때 어떠셨는지 의견 주시면 감사하겠습니다.