From c6bd058a12069c55c941bb6780ba1a8f1bb74857 Mon Sep 17 00:00:00 2001 From: donysony Date: Sun, 2 Jul 2023 02:31:30 +0900 Subject: [PATCH 1/5] =?UTF-8?q?ver1=20create,=20delete=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 18 ++++++++-- package.json | 4 +++ src/App.css | 16 +++++++-- src/App.js | 73 +++++++++++++++++++++++++++++++++++++++-- src/components/Form.css | 10 ++++++ src/components/Form.js | 32 ++++++++++++++++++ src/components/List.js | 30 +++++++++++++++++ src/index.css | 13 -------- tailwind.config.js | 9 +++++ 9 files changed, 183 insertions(+), 22 deletions(-) create mode 100644 src/components/Form.css create mode 100644 src/components/Form.js create mode 100644 src/components/List.js create mode 100644 tailwind.config.js diff --git a/package-lock.json b/package-lock.json index 96d43dc..3a8cafc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,7 +14,11 @@ "react": "^18.2.0", "react-dom": "^18.2.0", "react-scripts": "5.0.1", + "uuid": "^9.0.0", "web-vitals": "^2.1.4" + }, + "devDependencies": { + "tailwindcss": "^3.3.2" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -15425,6 +15429,14 @@ "websocket-driver": "^0.7.4" } }, + "node_modules/sockjs/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/source-list-map": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", @@ -16538,9 +16550,9 @@ } }, "node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", + "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==", "bin": { "uuid": "dist/bin/uuid" } diff --git a/package.json b/package.json index 9347367..8914095 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "react": "^18.2.0", "react-dom": "^18.2.0", "react-scripts": "5.0.1", + "uuid": "^9.0.0", "web-vitals": "^2.1.4" }, "scripts": { @@ -34,5 +35,8 @@ "last 1 firefox version", "last 1 safari version" ] + }, + "devDependencies": { + "tailwindcss": "^3.3.2" } } diff --git a/src/App.css b/src/App.css index 1037c8d..03c5847 100644 --- a/src/App.css +++ b/src/App.css @@ -1,4 +1,14 @@ -.App { - -} +@tailwind base; +@tailwind components; +@tailwind utilities; +@layer base { + h1 { + @apply text-2xl font-semibold + ; + } + h2 { + @apply text-xl; + } + +} \ No newline at end of file diff --git a/src/App.js b/src/App.js index 4b31b85..82d3992 100644 --- a/src/App.js +++ b/src/App.js @@ -1,10 +1,77 @@ - +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"; + +// const initiaMyDiary = localStorage.getItem("Diary") ? JSON.parse(localStorage.getItem("Diary")):[]; function App() { + + // const[DiaryData, setDiaryData] = useState(initiaMyDiary); + let[DiaryData, setDiaryData] = useState([ + // { + // id:"1", + // date:"7/1", + // content: "오늘은 피부과를 갔다" + // }, + // { + // id:"2", + // date:"7/2", + // content: "오늘은 용산를 갔다" + // } + + ]); + const[value, setValue] = useState(""); + + + + // const handleClick = useCallback((id) => { + // let newDiaryData = DiaryData.filter((data) => data.id !== id); //id가 같다면 삭제하도록 + // setDiaryData(newDiaryData); + // // console.log('newDiaryData',newDiaryData); + // // 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(); + 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] + ); + // localStorage.setItem('DiaryData', JSON.stringify([...DiaryData, newDiary])); + setValue(""); + } + + return ( -
- hello world! 변경변경 shshsh +
+
+
+

한줄 일기

+
+
+ +
); } diff --git a/src/components/Form.css b/src/components/Form.css new file mode 100644 index 0000000..89463d6 --- /dev/null +++ b/src/components/Form.css @@ -0,0 +1,10 @@ +.diary-input{ + width:250px; + height: 30px; + padding:0px; +} +.diary-submit{ + height: 30px; + margin-left: 10px; + +} \ No newline at end of file diff --git a/src/components/Form.js b/src/components/Form.js new file mode 100644 index 0000000..c4ff1c9 --- /dev/null +++ b/src/components/Form.js @@ -0,0 +1,32 @@ +import React from 'react' +import './Form.css' +const Form = ({value, setValue, handleSubmit}) => { + + const handleChange = (e) => { + setValue(e.target.value); + } + + + return ( + + + + + ) +} + +export default Form diff --git a/src/components/List.js b/src/components/List.js new file mode 100644 index 0000000..42050f4 --- /dev/null +++ b/src/components/List.js @@ -0,0 +1,30 @@ +import React from 'react' + +const List = ({handleClick, DiaryData, setDiaryData}) => { + + + + return ( +
+
+ 날짜내용 +
+
+ { DiaryData.map((data) => ( +
+ {data.date} + + {data.content} + + + + +
+ ))} +
+ ) +} + +export default List diff --git a/src/index.css b/src/index.css index ec2585e..e69de29 100644 --- a/src/index.css +++ b/src/index.css @@ -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; -} diff --git a/tailwind.config.js b/tailwind.config.js new file mode 100644 index 0000000..e5b64f3 --- /dev/null +++ b/tailwind.config.js @@ -0,0 +1,9 @@ +/** @type {import('tailwindcss').Config} */ +module.exports = { + content: ["./src/**/*.{html,js}"], + theme: { + extend: {}, + }, + plugins: [], +} + From eed167b0e3952678730e2ba928f1a84af506a548 Mon Sep 17 00:00:00 2001 From: donysony Date: Sun, 2 Jul 2023 23:22:37 +0900 Subject: [PATCH 2/5] =?UTF-8?q?=EC=88=98=EC=A0=95,=20=EB=A1=9C=EC=BB=AC?= =?UTF-8?q?=EC=8A=A4=ED=86=A0=EB=A6=AC=EC=A7=80=EC=97=90=20=EC=A0=80?= =?UTF-8?q?=EC=9E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.js | 50 ++++++++------------- src/components/List.js | 100 ++++++++++++++++++++++++++++++++--------- src/index.js | 2 - 3 files changed, 98 insertions(+), 54 deletions(-) diff --git a/src/App.js b/src/App.js index 82d3992..9153d52 100644 --- a/src/App.js +++ b/src/App.js @@ -4,42 +4,30 @@ import './App.css'; import Form from "./components/Form"; import List from "./components/List"; -// const initiaMyDiary = localStorage.getItem("Diary") ? JSON.parse(localStorage.getItem("Diary")):[]; +const initiaMyDiary = localStorage.getItem("Diary") ? JSON.parse(localStorage.getItem("Diary")):[]; function App() { - // const[DiaryData, setDiaryData] = useState(initiaMyDiary); - let[DiaryData, setDiaryData] = useState([ - // { - // id:"1", - // date:"7/1", - // content: "오늘은 피부과를 갔다" - // }, - // { - // id:"2", - // date:"7/2", - // content: "오늘은 용산를 갔다" - // } - - ]); + const[DiaryData, setDiaryData] = useState(initiaMyDiary); + // const[DiaryData, setDiaryData] = useState([]); const[value, setValue] = useState(""); - - - // const handleClick = useCallback((id) => { - // let newDiaryData = DiaryData.filter((data) => data.id !== id); //id가 같다면 삭제하도록 - // setDiaryData(newDiaryData); - // // console.log('newDiaryData',newDiaryData); - // // localStorage.setItem('Diary', JSON.stringify(newDiaryData)); - // }, - // [DiaryData] - // ) - const handleClick = (id)=>{ - console.log("handleClick", id); - let newDiaryData = DiaryData.filter((data) => data.id !== id); + //List에서 handleClick를 사용하기 때문에 리랜더링발생 --> 성능저하 + //useCallback() : DiaryData가 변하지 않는다면 함수는 새로 생성되지 않음(새로 생성되지 않으므로 메모리에 새로 할당되지 않고 동일 참조값을 사용) + const handleClick = useCallback((id) => { + let newDiaryData = DiaryData.filter((data) => data.id !== id); //id가 같다면 삭제하도록 setDiaryData(newDiaryData); - console.log('newDiaryData', newDiaryData); - } + console.log('newDiaryData',newDiaryData); + 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(); @@ -58,7 +46,7 @@ function App() { setDiaryData(prev => [...prev, newDiary] ); - // localStorage.setItem('DiaryData', JSON.stringify([...DiaryData, newDiary])); + localStorage.setItem('DiaryData', JSON.stringify([...DiaryData, newDiary])); setValue(""); } diff --git a/src/components/List.js b/src/components/List.js index 42050f4..3587339 100644 --- a/src/components/List.js +++ b/src/components/List.js @@ -1,30 +1,88 @@ -import React from 'react' +import React,{useState} from 'react' const List = ({handleClick, DiaryData, setDiaryData}) => { + console.log('DiaryData : ', DiaryData); + const [isEditing, setIsEditing] = useState(false); + const [editedContent, setEditedContent] = useState(""); + const [id, setId] = useState(""); + const [date, setDate] = useState(""); + //글 수정 + const handleEditChange = (event) => { + setEditedContent(event.target.value); + } - - return ( -
-
- 날짜내용 + //수정된 글 저장 + const handleSubmit = (event) =>{ + event.preventDefault(); + let newDiaryData = DiaryData.map(data =>{ + if(data.id === id){ + data.content = editedContent; + } + return data; + }) + setDiaryData(newDiaryData); + localStorage.setItem('DiaryData', JSON.stringify(newDiaryData)); + setIsEditing(false); + } + + + if(isEditing){ + //수정버튼을 눌렀을 때 + return ( +
+
+ 날짜내용 +
+
+
+
+ {date} +
+ +
+
+
+ + +
+
-
- { DiaryData.map((data) => ( -
- {data.date} - - {data.content} - - - - + ) + }else{ + return ( +
+
+ 날짜내용 +
+
+ { DiaryData.map((data) => ( +
+ {data.date} + + {data.content} + +
+ + +
+
+ ))}
- ))} -
- ) + ) + } } export default List diff --git a/src/index.js b/src/index.js index e2ab1f9..14bb570 100644 --- a/src/index.js +++ b/src/index.js @@ -5,8 +5,6 @@ import App from './App'; const root = ReactDOM.createRoot(document.getElementById('root')); root.render( - - ); From 75ccbec686b113aa7ea8d80808c200106e62b830 Mon Sep 17 00:00:00 2001 From: donysony Date: Mon, 3 Jul 2023 09:57:16 +0900 Subject: [PATCH 3/5] =?UTF-8?q?=EC=A3=BC=EC=84=9D=EC=B2=98=EB=A6=AC=20?= =?UTF-8?q?=EB=B0=8F=20=EB=A1=9C=EC=BB=AC=EC=8A=A4=ED=86=A0=EB=A6=AC?= =?UTF-8?q?=EC=A7=80=20key=EB=AA=85=20=ED=86=B5=ED=95=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.js | 11 ++++++++--- src/components/Form.js | 2 +- src/components/List.js | 7 +++---- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/App.js b/src/App.js index 9153d52..acd6b24 100644 --- a/src/App.js +++ b/src/App.js @@ -3,11 +3,12 @@ import { v4 as uuidv4 } from 'uuid'; import './App.css'; import Form from "./components/Form"; import List from "./components/List"; - +//만약 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(""); @@ -18,6 +19,9 @@ function App() { 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] @@ -46,7 +50,8 @@ function App() { setDiaryData(prev => [...prev, newDiary] ); - localStorage.setItem('DiaryData', JSON.stringify([...DiaryData, newDiary])); + //원래있던 DiaryData를 넣어준 후 newDiary를 넣어줌 + localStorage.setItem('Diary', JSON.stringify([...DiaryData, newDiary])); setValue(""); } diff --git a/src/components/Form.js b/src/components/Form.js index c4ff1c9..950115c 100644 --- a/src/components/Form.js +++ b/src/components/Form.js @@ -1,7 +1,7 @@ import React from 'react' import './Form.css' const Form = ({value, setValue, handleSubmit}) => { - + console.log('Form Component') const handleChange = (e) => { setValue(e.target.value); } diff --git a/src/components/List.js b/src/components/List.js index 3587339..6866ae1 100644 --- a/src/components/List.js +++ b/src/components/List.js @@ -1,7 +1,7 @@ import React,{useState} from 'react' const List = ({handleClick, DiaryData, setDiaryData}) => { - + console.log('List Component') console.log('DiaryData : ', DiaryData); const [isEditing, setIsEditing] = useState(false); const [editedContent, setEditedContent] = useState(""); @@ -22,7 +22,7 @@ const List = ({handleClick, DiaryData, setDiaryData}) => { return data; }) setDiaryData(newDiaryData); - localStorage.setItem('DiaryData', JSON.stringify(newDiaryData)); + localStorage.setItem('Diary', JSON.stringify(newDiaryData)); setIsEditing(false); } @@ -81,8 +81,7 @@ const List = ({handleClick, DiaryData, setDiaryData}) => {
))}
- ) - } + )} } export default List From c83f5e2e7462c1609227d9ab2b165c3686762a81 Mon Sep 17 00:00:00 2001 From: donysony Date: Mon, 3 Jul 2023 18:34:35 +0900 Subject: [PATCH 4/5] =?UTF-8?q?React.memo=EC=A0=81=EC=9A=A9=20=EB=B0=8F=20?= =?UTF-8?q?handleEdit=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/List.js | 6 ++++-- src/components/Lists.js | 0 2 files changed, 4 insertions(+), 2 deletions(-) create mode 100644 src/components/Lists.js diff --git a/src/components/List.js b/src/components/List.js index 6866ae1..fd7d9bf 100644 --- a/src/components/List.js +++ b/src/components/List.js @@ -7,6 +7,8 @@ const List = ({handleClick, DiaryData, setDiaryData}) => { const [editedContent, setEditedContent] = useState(""); const [id, setId] = useState(""); const [date, setDate] = useState(""); + //함수를 생성해서 + const hanldeEdit = (data) => {setIsEditing(true); setId(data.id); setEditedContent(data.content); setDate(data.date)} //글 수정 const handleEditChange = (event) => { setEditedContent(event.target.value); @@ -71,7 +73,7 @@ const List = ({handleClick, DiaryData, setDiaryData}) => { {data.content}
-
- +
); diff --git a/src/components/List.js b/src/components/List.js index fd7d9bf..f622c42 100644 --- a/src/components/List.js +++ b/src/components/List.js @@ -1,14 +1,15 @@ import React,{useState} from 'react' -const List = ({handleClick, DiaryData, setDiaryData}) => { +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(""); - const [id, setId] = useState(""); - const [date, setDate] = useState(""); - //함수를 생성해서 - const hanldeEdit = (data) => {setIsEditing(true); setId(data.id); setEditedContent(data.content); setDate(data.date)} + const [editedContent, setEditedContent] = useState(content); + + //넘기는 인자값이 많을 경우 함수를 생성해서 할수도 있음 + // 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); @@ -32,15 +33,11 @@ const List = ({handleClick, DiaryData, setDiaryData}) => { if(isEditing){ //수정버튼을 눌렀을 때 return ( -
-
- 날짜내용 -
-
+
{date} - + { ) }else{ return ( -
-
- 날짜내용 -
-
- { DiaryData.map((data) => ( -
- {data.date} - - {data.content} - -
- - +
+
+
+ {date} + {/* */} +
+ {content} +
+ {/* */} +
+
+ +
- ))}
+ + + )} } diff --git a/src/components/Lists.js b/src/components/Lists.js index e69de29..39ea31a 100644 --- a/src/components/Lists.js +++ b/src/components/Lists.js @@ -0,0 +1,28 @@ +import React from 'react' +import List from './List' + +const Lists = ({handleClick, DiaryData, setDiaryData}) => { + console.log("Lists DiaryData : ", DiaryData); + return ( +
+
+
+ 날짜내용 +
+
+ { DiaryData.map((data) => ( + + ))} +
+
+ ) +} + +export default React.memo(Lists);