From d7c22e878ee12c6ab2e2e5481fc202c08fb9fbff Mon Sep 17 00:00:00 2001 From: 4Bee <4bee.code@gmail.com> Date: Sun, 6 Oct 2024 15:52:14 +0900 Subject: [PATCH 1/8] =?UTF-8?q?=F0=9F=9A=A9:=20=EB=B2=84=ED=8A=BC=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=20=EB=B0=8F=20=EC=A0=81=EC=9A=A9=20=ED=99=95?= =?UTF-8?q?=EC=9D=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.tsx | 45 +++++++++++++++++++-------------------------- 1 file changed, 19 insertions(+), 26 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 391eea5..f5c831a 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,11 +1,11 @@ -import { useState, useEffect } from "react"; -import reactLogo from "./assets/react.svg"; -import viteLogo from "/vite.svg"; +import { useEffect } from "react"; +// import reactLogo from "./assets/react.svg"; +// import viteLogo from "/vite.svg"; import "./App.css"; import { validateData } from "./test"; // test.ts 파일을 import function App() { - const [count, setCount] = useState(0); + // const [count, setCount] = useState(0); useEffect(() => { // 컴포넌트가 마운트될 때 test.ts의 validateData 함수 실행 @@ -13,28 +13,21 @@ function App() { }, []); return ( - <> -
- - Vite logo - - - React logo - -
-

Vite + React

-
- -

- Edit src/App.tsx and save to test HMR -

-
-

- Click on the Vite and React logos to learn more -

- +
+
test
+
{ + console.log('test'); + }}>Button
+
); } From 854d3793404f132c79f63dbeeefda6c2c9e026b1 Mon Sep 17 00:00:00 2001 From: 4Bee <4bee.code@gmail.com> Date: Sun, 6 Oct 2024 20:40:12 +0900 Subject: [PATCH 2/8] =?UTF-8?q?=F0=9F=9A=A9:=20=EB=B2=84=ED=8A=BC=EC=9D=84?= =?UTF-8?q?=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=EB=A1=9C=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.tsx | 18 +++------- src/shared/components/Button.components.tsx | 39 +++++++++++++++++++++ 2 files changed, 44 insertions(+), 13 deletions(-) create mode 100644 src/shared/components/Button.components.tsx diff --git a/src/App.tsx b/src/App.tsx index f5c831a..a67286d 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -2,7 +2,10 @@ import { useEffect } from "react"; // import reactLogo from "./assets/react.svg"; // import viteLogo from "/vite.svg"; import "./App.css"; -import { validateData } from "./test"; // test.ts 파일을 import +import ButtonComponents from "./shared/components/button.components"; +import { validateData } from "./test"; // test.ts 파일을 + +const Button = ButtonComponents; function App() { // const [count, setCount] = useState(0); @@ -15,18 +18,7 @@ function App() { return (
test
-
{ - console.log('test'); - }}>Button
+
); } diff --git a/src/shared/components/Button.components.tsx b/src/shared/components/Button.components.tsx new file mode 100644 index 0000000..77f8830 --- /dev/null +++ b/src/shared/components/Button.components.tsx @@ -0,0 +1,39 @@ +import { useState } from "react"; + +const ButtonComponents = () => { + const [isHover, setHover] = useState(false); + + return ( +
+
+
{ + setHover(true); + }} + onMouseLeave={() => { + setHover(false); + }} + onClick={() => { + console.log('Button clicked'); + }} + role="button" // 접근성 향상 + > + Button +
+
+
+ ) +}; + +export default ButtonComponents; \ No newline at end of file From 052936a3ef1828fca8de17c1cd16996247f6ead9 Mon Sep 17 00:00:00 2001 From: 4Bee <4bee.code@gmail.com> Date: Sun, 6 Oct 2024 20:57:55 +0900 Subject: [PATCH 3/8] =?UTF-8?q?=F0=9F=9A=A9:=20Zod=20=EC=A0=81=EC=9A=A9=20?= =?UTF-8?q?=EB=B0=8F=20Zod=20=EA=B2=80=EC=A6=9D=20=EC=8B=9C=EC=8A=A4?= =?UTF-8?q?=ED=85=9C=20=EB=AF=B8=EC=A0=81=EC=9A=A9=EC=9C=BC=EB=A1=9C=20Err?= =?UTF-8?q?or=20=EB=B0=9C=EC=83=9D=20=ED=99=95=EC=9D=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 12 +++++++++++- package.json | 3 ++- src/App.tsx | 4 ++-- src/shared/components/Button.components.tsx | 16 ++++++++++++++-- 4 files changed, 29 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4972f26..6573eb7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,8 @@ "fp-ts": "^2.16.9", "io-ts": "^2.2.21", "react": "^18.3.1", - "react-dom": "^18.3.1" + "react-dom": "^18.3.1", + "zod": "^3.23.8" }, "devDependencies": { "@eslint/js": "^9.9.0", @@ -3329,6 +3330,15 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/zod": { + "version": "3.23.8", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz", + "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } } } } diff --git a/package.json b/package.json index 1975770..34b0140 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,8 @@ "fp-ts": "^2.16.9", "io-ts": "^2.2.21", "react": "^18.3.1", - "react-dom": "^18.3.1" + "react-dom": "^18.3.1", + "zod": "^3.23.8" }, "devDependencies": { "@eslint/js": "^9.9.0", diff --git a/src/App.tsx b/src/App.tsx index a67286d..506cbca 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -9,7 +9,7 @@ const Button = ButtonComponents; function App() { // const [count, setCount] = useState(0); - + // '#3d3da1' : '#5353ea' useEffect(() => { // 컴포넌트가 마운트될 때 test.ts의 validateData 함수 실행 validateData(); @@ -18,7 +18,7 @@ function App() { return (
test
-
); } diff --git a/src/shared/components/Button.components.tsx b/src/shared/components/Button.components.tsx index 77f8830..397c584 100644 --- a/src/shared/components/Button.components.tsx +++ b/src/shared/components/Button.components.tsx @@ -1,6 +1,18 @@ import { useState } from "react"; +import Z from "zod"; -const ButtonComponents = () => { +//interface +//Zod about props +// 1. zod로 props 스키마 정의 +const buttonPropsSchema = Z.object({ + EnterColor: Z.string(), + LeaveColor: Z.string(), +}) + +// 2. TypeScript 타입으로 추출 +type ButtonProps = Z.infer; + +const ButtonComponents = ({EnterColor, LeaveColor}:ButtonProps) => { const [isHover, setHover] = useState(false); return ( @@ -13,7 +25,7 @@ const ButtonComponents = () => { alignItems: 'center', width: '100px', height: '50px', - background: isHover ? '#3d3da1' : '#5353ea', + background: isHover ? EnterColor : LeaveColor, color: 'white', borderRadius: '7px', cursor: 'pointer', From 64a9aa19fea6fce3f0ea34d7ce4d4d9cf183638e Mon Sep 17 00:00:00 2001 From: 4Bee <4bee.code@gmail.com> Date: Sun, 6 Oct 2024 21:00:28 +0900 Subject: [PATCH 4/8] =?UTF-8?q?=F0=9F=9A=A9:=20Zod=EB=A5=BC=20=EC=82=AC?= =?UTF-8?q?=EC=9A=A9=ED=95=B4=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20?= =?UTF-8?q?=EC=A0=81=EC=9A=A9=20=EB=B0=A9=EB=B2=95=20=EC=A3=BC=EC=84=9D?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/shared/components/Button.components.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/shared/components/Button.components.tsx b/src/shared/components/Button.components.tsx index 397c584..993ee10 100644 --- a/src/shared/components/Button.components.tsx +++ b/src/shared/components/Button.components.tsx @@ -12,6 +12,8 @@ const buttonPropsSchema = Z.object({ // 2. TypeScript 타입으로 추출 type ButtonProps = Z.infer; +// 3. 컴포넌트에 타입 설정: FC Generics로 적용하지 않고 해당 Props에 Type을 적용 +// FC 사용방법은 PR Link 참고 const ButtonComponents = ({EnterColor, LeaveColor}:ButtonProps) => { const [isHover, setHover] = useState(false); From 12a7dfbc989a86f6351c7272d402f860a7215ff4 Mon Sep 17 00:00:00 2001 From: 4Bee <4bee.code@gmail.com> Date: Sun, 6 Oct 2024 21:07:25 +0900 Subject: [PATCH 5/8] =?UTF-8?q?=F0=9F=90=9B:=20=EB=9F=B0=ED=83=80=EC=9E=84?= =?UTF-8?q?=20Props=20=EA=B2=80=EC=A6=9D,=20Parse=20=EC=A0=81=EC=9A=A9?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20Error=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/shared/components/Button.components.tsx | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/shared/components/Button.components.tsx b/src/shared/components/Button.components.tsx index 993ee10..901d32a 100644 --- a/src/shared/components/Button.components.tsx +++ b/src/shared/components/Button.components.tsx @@ -4,7 +4,7 @@ import Z from "zod"; //interface //Zod about props // 1. zod로 props 스키마 정의 -const buttonPropsSchema = Z.object({ +const buttonPropsSchema = Z.object({ //4. Error: 런타임 Props 검증, Parse 미사용으로 Error 발생 EnterColor: Z.string(), LeaveColor: Z.string(), }) @@ -12,11 +12,25 @@ const buttonPropsSchema = Z.object({ // 2. TypeScript 타입으로 추출 type ButtonProps = Z.infer; +// 2-1. 바로 타입만 추출하고 스키마 제거 +/** +type ButtonProps = z.infer< + z.object({ + EnterColor: z.string(), + LeaveColor: z.string(), + }) +>; +*/ // 3. 컴포넌트에 타입 설정: FC Generics로 적용하지 않고 해당 Props에 Type을 적용 // FC 사용방법은 PR Link 참고 -const ButtonComponents = ({EnterColor, LeaveColor}:ButtonProps) => { +const ButtonComponents = (props:ButtonProps) => { const [isHover, setHover] = useState(false); +// 4-1. 직접적으로 Props 변수를 생성 + const { EnterColor, LeaveColor } = props; +// 4-2. 런타임 Props 검증 + buttonPropsSchema.parse(props); + return (
From 4b4ce7275c0cc04a96ec58df79653a215d7a91f5 Mon Sep 17 00:00:00 2001 From: 4Bee <4bee.code@gmail.com> Date: Sun, 6 Oct 2024 21:10:18 +0900 Subject: [PATCH 6/8] =?UTF-8?q?=F0=9F=A7=AA:=20=EA=B8=B0=EC=A1=B4=20Button?= =?UTF-8?q?Components=EB=A5=BC=20test=ED=8C=8C=EC=9D=BC=EB=A1=9C=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=20=EB=B0=8F=20=EB=B6=84=EB=A6=AC=ED=95=A0=20?= =?UTF-8?q?=EC=98=88=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.tsx | 3 +- .../components/Button.components.test.tsx | 67 +++++++++++++++++++ 2 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 src/shared/components/Button.components.test.tsx diff --git a/src/App.tsx b/src/App.tsx index 506cbca..2d1467d 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -2,7 +2,8 @@ import { useEffect } from "react"; // import reactLogo from "./assets/react.svg"; // import viteLogo from "/vite.svg"; import "./App.css"; -import ButtonComponents from "./shared/components/button.components"; +// import ButtonComponents from "./shared/components/button.components"; //원문 파일 +import ButtonComponents from "./shared/components/Button.components.test"; //Test 파일로 대체 import { validateData } from "./test"; // test.ts 파일을 const Button = ButtonComponents; diff --git a/src/shared/components/Button.components.test.tsx b/src/shared/components/Button.components.test.tsx new file mode 100644 index 0000000..901d32a --- /dev/null +++ b/src/shared/components/Button.components.test.tsx @@ -0,0 +1,67 @@ +import { useState } from "react"; +import Z from "zod"; + +//interface +//Zod about props +// 1. zod로 props 스키마 정의 +const buttonPropsSchema = Z.object({ //4. Error: 런타임 Props 검증, Parse 미사용으로 Error 발생 + EnterColor: Z.string(), + LeaveColor: Z.string(), +}) + +// 2. TypeScript 타입으로 추출 +type ButtonProps = Z.infer; + +// 2-1. 바로 타입만 추출하고 스키마 제거 +/** +type ButtonProps = z.infer< + z.object({ + EnterColor: z.string(), + LeaveColor: z.string(), + }) +>; +*/ +// 3. 컴포넌트에 타입 설정: FC Generics로 적용하지 않고 해당 Props에 Type을 적용 +// FC 사용방법은 PR Link 참고 +const ButtonComponents = (props:ButtonProps) => { + const [isHover, setHover] = useState(false); + +// 4-1. 직접적으로 Props 변수를 생성 + const { EnterColor, LeaveColor } = props; +// 4-2. 런타임 Props 검증 + buttonPropsSchema.parse(props); + + return ( +
+
+
{ + setHover(true); + }} + onMouseLeave={() => { + setHover(false); + }} + onClick={() => { + console.log('Button clicked'); + }} + role="button" // 접근성 향상 + > + Button +
+
+
+ ) +}; + +export default ButtonComponents; \ No newline at end of file From 72dbcc4399f5649a04306fac30d335c33afb39d8 Mon Sep 17 00:00:00 2001 From: 4Bee <4bee.code@gmail.com> Date: Sun, 6 Oct 2024 21:18:20 +0900 Subject: [PATCH 7/8] =?UTF-8?q?=F0=9F=A7=AA:=20Button=20Props=20=EB=9F=B0?= =?UTF-8?q?=ED=83=80=EC=9E=84=20=EA=B2=80=EC=A6=9D=EC=9D=84=20try,=20catch?= =?UTF-8?q?=EB=A1=9C=20=EC=88=98=ED=96=89=20=EC=84=B1=EA=B3=B5=20=EC=97=AC?= =?UTF-8?q?=EB=B6=80=20=ED=99=95=EC=9D=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/shared/components/Button.components.test.tsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/shared/components/Button.components.test.tsx b/src/shared/components/Button.components.test.tsx index 901d32a..00f26e7 100644 --- a/src/shared/components/Button.components.test.tsx +++ b/src/shared/components/Button.components.test.tsx @@ -29,7 +29,12 @@ const ButtonComponents = (props:ButtonProps) => { // 4-1. 직접적으로 Props 변수를 생성 const { EnterColor, LeaveColor } = props; // 4-2. 런타임 Props 검증 - buttonPropsSchema.parse(props); + try { + buttonPropsSchema.parse(props); + console.log("Props validation successful"); // 유효성 검증이 성공하면 이 메시지가 출력됩니다. + } catch (err) { + console.error("Props validation failed", err); // 검증 실패 시 오류 메시지 출력 + } return (
From 411f2f4cbbff668ef1895fd34e61bdb6a97882b7 Mon Sep 17 00:00:00 2001 From: 4Bee <4bee.code@gmail.com> Date: Sun, 6 Oct 2024 21:22:24 +0900 Subject: [PATCH 8/8] =?UTF-8?q?=F0=9F=9A=A9:=20Button=20Props=20=EB=9F=B0?= =?UTF-8?q?=ED=83=80=EC=9E=84=20=EA=B2=80=EC=A6=9D=20=ED=99=95=EC=9D=B8=20?= =?UTF-8?q?=EB=B0=8F=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/shared/components/Button.components.test.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/shared/components/Button.components.test.tsx b/src/shared/components/Button.components.test.tsx index 00f26e7..da36cac 100644 --- a/src/shared/components/Button.components.test.tsx +++ b/src/shared/components/Button.components.test.tsx @@ -26,9 +26,10 @@ type ButtonProps = z.infer< const ButtonComponents = (props:ButtonProps) => { const [isHover, setHover] = useState(false); -// 4-1. 직접적으로 Props 변수를 생성 + // 4-1. 직접적으로 Props 변수를 생성 const { EnterColor, LeaveColor } = props; -// 4-2. 런타임 Props 검증 + + // 4-2. 런타임 Props 검증 try { buttonPropsSchema.parse(props); console.log("Props validation successful"); // 유효성 검증이 성공하면 이 메시지가 출력됩니다.