From 2065cf8b8d35529a8b609077e2296d206e7cd26c Mon Sep 17 00:00:00 2001 From: Seong-Jin Kim Date: Wed, 24 Aug 2022 05:55:46 +0900 Subject: [PATCH 01/25] doc: basic cheatsheets --- README.md | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index f0db150..1c6c467 100644 --- a/README.md +++ b/README.md @@ -1 +1,38 @@ -# react-typescript-cheatsheet-kr \ No newline at end of file +# React+TypeScript Cheatsheets ํ•œ๊ตญ์–ดํŒ ๐Ÿ‡ฐ๐Ÿ‡ท + +TypeScript์— ์ž…๋ฌธํ•˜๋Š” React ๊ฐœ๋ฐœ์ž๋ฅผ ์œ„ํ•œ ์น˜ํŠธ์‹œํŠธ(Cheetsheets) + +--- + + + react + ts logo + + +[**์›น ๋‹คํ๋จผํŠธ**](https://react-typescript-cheatsheet.netlify.app/docs/basic/setup) | +[**์˜์–ดํŒ**](https://github.com/typescript-cheatsheets/react-typescript-cheatsheet-es) | +[ํ”„๋กœ์ ํŠธ์— ๊ธฐ์—ฌํ•˜๊ธฐ]() | +[์งˆ๋ฌธํ•˜๊ธฐ]() + +:wave: ๋ณธ ๋ฆฌํฌ์ง€ํ† ๋ฆฌ๋Š” [@ryan_kim_kr](https://twitter.com/ryan_kim_kr)์— ์˜ํ•ด ๊ด€๋ฆฌ๋˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐœ๋ฐœ์ž๋‹˜์ด React์™€ ํ•จ๊ป˜ TypeScript๋ฅผ ์‚ฌ์šฉํ•ด๋ณด๊ณ ์ž ํ•˜์‹œ๋‹ค๋‹ˆ ์ •๋ง ๊ธฐ์œ ์†Œ์‹์ด๊ตฐ์š”! ์ž˜๋ชป๋œ ๋ถ€๋ถ„์ด ๋ฐœ๊ฒฌ๋˜์–ด ์ˆ˜์ •์ด ํ•„์š”ํ•˜๊ฑฐ๋‚˜ ๋ˆ„๋ฝ๋œ ๋ถ€๋ถ„์ด ์žˆ๋‹ค๋ฉด ๊ฐœ์„  ๋˜์–ด์•ผ ํ•  ์‚ฌํ•ญ์„ [์ด์Šˆ ๋“ฑ๋ก](https://github.com/typescript-cheatsheets/react-typescript-cheatsheet-kr/issues/new)ํ•ด ์ฃผ์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค. :+1: + +--- + +[![All Contributors](https://img.shields.io/github/contributors/typescript-cheatsheets/react-typescript-cheatsheet?color=orange&style=flat-square)](/COLABORADORES.md) + +# All React + TypeScript Cheatsheets + +- [๊ธฐ์ดˆ ์น˜ํŠธ์‹œํŠธ]()๋Š” React ๊ฐœ๋ฐœ์ž๊ฐ€ React app์—์„œ TS ์‚ฌ์šฉ์„ ์‹œ์ž‘ํ•˜๋Š” ๊ฒƒ์— ๋„์›€์„ ์ฃผ๊ธฐ ์œ„ํ•œ ๋‚ด์šฉ์ด ์ฃผ๋ฅผ ์ด๋ฃน๋‹ˆ๋‹ค. + - ๋ชจ๋ฒ” ์‚ฌ๋ก€(Best Practices)๋ผ๊ณ  ์—ฌ๊ฒจ์ง€๋Š”, ๋ณต์‚ฌ + ๋ถ™์—ฌ๋„ฃ๊ธฐ ๊ฐ€๋Šฅํ•œ ์˜ˆ์‹œ + - ๊ธฐ๋ณธ์ ์ธ TS Types ์‚ฌ์šฉ๋ฒ•๊ณผ ์„ค์ • ๋ฐฉ๋ฒ• + - ์ž์ฃผ ๋ฌป๋Š” ์งˆ๋ฌธ(FAQ)์— ๋Œ€ํ•œ ๋‹ต๋ณ€ + - Generic type logic์€ ๊นŠ์ด ๋‹ค๋ฃจ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ ๋Œ€์‹ , ์ดˆ์‹ฌ์ž๋“ค์„ ์œ„ํ•ด ๊ฐ„๋‹จํ•œ ํŠธ๋Ÿฌ๋ธ”์ŠˆํŒ… ๊ธฐ์ˆ ๋“ค์„ ์†Œ๊ฐœํ•ฉ๋‹ˆ๋‹ค. + - ๊ธฐ์ดˆ ์น˜ํŠธ์‹œํŠธ์˜ ๋ชฉ์ ์€ ๊ฐœ๋ฐœ์ž๊ฐ€ TypeScript์— ๋Œ€ํ•ด ๋„ˆ๋ฌด ๋งŽ์€ ๊ณต๋ถ€๋ฅผ ํ•˜์ง€ ์•Š๊ณ ์„œ๋„ **์‹œ๊ฐ„ ํšจ์œจ์ **์œผ๋กœ React ๊ฐœ๋ฐœ์— TypeScript๋ฅผ ๋น ๋ฅด๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๋•๊ธฐ ์œ„ํ•ฉ๋‹ˆ๋‹ค. +- [๊ณ ๊ธ‰ ์น˜ํŠธ์‹œํŠธ]() +- [๋งˆ์ด๊ทธ๋ ˆ์ดํŒ… ์น˜ํŠธ์‹œํŠธ]() +- [HOC ์น˜ํŠธ์‹œํŠธ]() From eaabdd874c6d490516634a764d6a58070a124c9f Mon Sep 17 00:00:00 2001 From: Seong-Jin Kim Date: Wed, 24 Aug 2022 16:09:36 +0900 Subject: [PATCH 02/25] doc: translate The Adcanced Cheatsheet --- README.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 1c6c467..a5e9390 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,10 @@ TypeScript์— ์ž…๋ฌธํ•˜๋Š” React ๊ฐœ๋ฐœ์ž๋ฅผ ์œ„ํ•œ ์น˜ํŠธ์‹œํŠธ(Cheetsheets) - ๊ธฐ๋ณธ์ ์ธ TS Types ์‚ฌ์šฉ๋ฒ•๊ณผ ์„ค์ • ๋ฐฉ๋ฒ• - ์ž์ฃผ ๋ฌป๋Š” ์งˆ๋ฌธ(FAQ)์— ๋Œ€ํ•œ ๋‹ต๋ณ€ - Generic type logic์€ ๊นŠ์ด ๋‹ค๋ฃจ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ ๋Œ€์‹ , ์ดˆ์‹ฌ์ž๋“ค์„ ์œ„ํ•ด ๊ฐ„๋‹จํ•œ ํŠธ๋Ÿฌ๋ธ”์ŠˆํŒ… ๊ธฐ์ˆ ๋“ค์„ ์†Œ๊ฐœํ•ฉ๋‹ˆ๋‹ค. - - ๊ธฐ์ดˆ ์น˜ํŠธ์‹œํŠธ์˜ ๋ชฉ์ ์€ ๊ฐœ๋ฐœ์ž๊ฐ€ TypeScript์— ๋Œ€ํ•ด ๋„ˆ๋ฌด ๋งŽ์€ ๊ณต๋ถ€๋ฅผ ํ•˜์ง€ ์•Š๊ณ ์„œ๋„ **์‹œ๊ฐ„ ํšจ์œจ์ **์œผ๋กœ React ๊ฐœ๋ฐœ์— TypeScript๋ฅผ ๋น ๋ฅด๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๋•๊ธฐ ์œ„ํ•ฉ๋‹ˆ๋‹ค. -- [๊ณ ๊ธ‰ ์น˜ํŠธ์‹œํŠธ]() + - ๊ธฐ์ดˆ ์น˜ํŠธ์‹œํŠธ๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ TypeScript์— ๋Œ€ํ•ด ๋„ˆ๋ฌด ๋งŽ์€ ๊ณต๋ถ€๋ฅผ ํ•˜์ง€ ์•Š๊ณ ์„œ๋„ **์‹œ๊ฐ„ ํšจ์œจ์ **์œผ๋กœ React ๊ฐœ๋ฐœ์— TypeScript๋ฅผ ๋น ๋ฅด๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๋•๋Š” ๋ฐ ๊ทธ ๋ชฉ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. +- [๊ณ ๊ธ‰ ์น˜ํŠธ์‹œํŠธ]()๋Š” ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ type utilities/functions/render prop/higher order copmonents ๋˜๋Š” TS+React ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ž‘์„ฑํ•˜๊ณ ์ž ํ•˜๋Š” ๊ฐœ๋ฐœ์ž๋ฅผ ์œ„ํ•ด generic types์˜ ๊ณ ๊ธ‰ ์‚ฌ์šฉ๋ฒ•์— ๋Œ€ํ•œ ์ดํ•ด๋ฅผ ๋•์Šต๋‹ˆ๋‹ค. + - ์ „๋ฌธ์ ์ธ ๊ฐœ๋ฐœ์ž๋“ค์„ ์œ„ํ•œ ๋‹ค์–‘ํ•œ ํŒ๊ณผ ์š”๋ น๋“ค์„ ์†Œ๊ฐœํ•ฉ๋‹ˆ๋‹ค. + - DefinitelyTyped์— ๊ธฐ์—ฌํ•˜๊ธฐ ์œ„ํ•œ ์กฐ์–ธ์„ ๋“œ๋ฆฝ๋‹ˆ๋‹ค. + - ๊ณ ๊ธ‰ ์น˜ํŠธ์‹œํŠธ๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ TypeScript๋ฅผ ์ตœ๋Œ€ํ•œ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๋•๋Š” ๋ฐ ๊ทธ ๋ชฉ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. - [๋งˆ์ด๊ทธ๋ ˆ์ดํŒ… ์น˜ํŠธ์‹œํŠธ]() - [HOC ์น˜ํŠธ์‹œํŠธ]() From 9cbe031f3f67ffc4f832111adc60148395abf3a8 Mon Sep 17 00:00:00 2001 From: Seong-Jin Kim Date: Wed, 24 Aug 2022 18:03:24 +0900 Subject: [PATCH 03/25] doc: translate Readme: migrating cheatsheet, hoc cheatsheet --- README.md | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index a5e9390..c558dae 100644 --- a/README.md +++ b/README.md @@ -27,15 +27,25 @@ TypeScript์— ์ž…๋ฌธํ•˜๋Š” React ๊ฐœ๋ฐœ์ž๋ฅผ ์œ„ํ•œ ์น˜ํŠธ์‹œํŠธ(Cheetsheets) # All React + TypeScript Cheatsheets -- [๊ธฐ์ดˆ ์น˜ํŠธ์‹œํŠธ]()๋Š” React ๊ฐœ๋ฐœ์ž๊ฐ€ React app์—์„œ TS ์‚ฌ์šฉ์„ ์‹œ์ž‘ํ•˜๋Š” ๊ฒƒ์— ๋„์›€์„ ์ฃผ๊ธฐ ์œ„ํ•œ ๋‚ด์šฉ์ด ์ฃผ๋ฅผ ์ด๋ฃน๋‹ˆ๋‹ค. +- [๊ธฐ์ดˆ ์น˜ํŠธ์‹œํŠธ(The Basic Cheatsheet)]()๋Š” React ๊ฐœ๋ฐœ์ž๊ฐ€ React app์—์„œ TS ์‚ฌ์šฉ์„ ์‹œ์ž‘ํ•˜๋Š” ๊ฒƒ์— ๋„์›€์„ ์ฃผ๊ธฐ ์œ„ํ•œ ๋‚ด์šฉ์ด ์ฃผ๋ฅผ ์ด๋ฃน๋‹ˆ๋‹ค. - ๋ชจ๋ฒ” ์‚ฌ๋ก€(Best Practices)๋ผ๊ณ  ์—ฌ๊ฒจ์ง€๋Š”, ๋ณต์‚ฌ + ๋ถ™์—ฌ๋„ฃ๊ธฐ ๊ฐ€๋Šฅํ•œ ์˜ˆ์‹œ - ๊ธฐ๋ณธ์ ์ธ TS Types ์‚ฌ์šฉ๋ฒ•๊ณผ ์„ค์ • ๋ฐฉ๋ฒ• - ์ž์ฃผ ๋ฌป๋Š” ์งˆ๋ฌธ(FAQ)์— ๋Œ€ํ•œ ๋‹ต๋ณ€ - Generic type logic์€ ๊นŠ์ด ๋‹ค๋ฃจ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ ๋Œ€์‹ , ์ดˆ์‹ฌ์ž๋“ค์„ ์œ„ํ•ด ๊ฐ„๋‹จํ•œ ํŠธ๋Ÿฌ๋ธ”์ŠˆํŒ… ๊ธฐ์ˆ ๋“ค์„ ์†Œ๊ฐœํ•ฉ๋‹ˆ๋‹ค. - ๊ธฐ์ดˆ ์น˜ํŠธ์‹œํŠธ๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ TypeScript์— ๋Œ€ํ•ด ๋„ˆ๋ฌด ๋งŽ์€ ๊ณต๋ถ€๋ฅผ ํ•˜์ง€ ์•Š๊ณ ์„œ๋„ **์‹œ๊ฐ„ ํšจ์œจ์ **์œผ๋กœ React ๊ฐœ๋ฐœ์— TypeScript๋ฅผ ๋น ๋ฅด๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๋•๋Š” ๋ฐ ๊ทธ ๋ชฉ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. -- [๊ณ ๊ธ‰ ์น˜ํŠธ์‹œํŠธ]()๋Š” ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ type utilities/functions/render prop/higher order copmonents ๋˜๋Š” TS+React ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ž‘์„ฑํ•˜๊ณ ์ž ํ•˜๋Š” ๊ฐœ๋ฐœ์ž๋ฅผ ์œ„ํ•ด generic types์˜ ๊ณ ๊ธ‰ ์‚ฌ์šฉ๋ฒ•์— ๋Œ€ํ•œ ์ดํ•ด๋ฅผ ๋•์Šต๋‹ˆ๋‹ค. +- [๊ณ ๊ธ‰ ์น˜ํŠธ์‹œํŠธ(The Advanced Cheatsheet)]()๋Š” ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ type utilities/functions/render prop/higher order copmonents ๋˜๋Š” TS+React ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ž‘์„ฑํ•˜๊ณ ์ž ํ•˜๋Š” ๊ฐœ๋ฐœ์ž๋ฅผ ์œ„ํ•ด generic types์˜ ๊ณ ๊ธ‰ ์‚ฌ์šฉ๋ฒ•์— ๋Œ€ํ•œ ์ดํ•ด๋ฅผ ๋•์Šต๋‹ˆ๋‹ค. - ์ „๋ฌธ์ ์ธ ๊ฐœ๋ฐœ์ž๋“ค์„ ์œ„ํ•œ ๋‹ค์–‘ํ•œ ํŒ๊ณผ ์š”๋ น๋“ค์„ ์†Œ๊ฐœํ•ฉ๋‹ˆ๋‹ค. - DefinitelyTyped์— ๊ธฐ์—ฌํ•˜๊ธฐ ์œ„ํ•œ ์กฐ์–ธ์„ ๋“œ๋ฆฝ๋‹ˆ๋‹ค. - ๊ณ ๊ธ‰ ์น˜ํŠธ์‹œํŠธ๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ TypeScript๋ฅผ ์ตœ๋Œ€ํ•œ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๋•๋Š” ๋ฐ ๊ทธ ๋ชฉ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. -- [๋งˆ์ด๊ทธ๋ ˆ์ดํŒ… ์น˜ํŠธ์‹œํŠธ]() -- [HOC ์น˜ํŠธ์‹œํŠธ]() +- [๋งˆ์ด๊ทธ๋ ˆ์ดํŒ… ์น˜ํŠธ์‹œํŠธ(The Migrating Cheatsheet)]()๋Š” ๋Œ€๊ทœ๋ชจ ์ฝ”๋“œ๋ฒ ์ด์Šค๋ฅผ JS ๋˜๋Š” Flow์—์„œ TypsScript๋กœ ์ ์ง„์ ์œผ๋กœ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ํ•˜๋Š” ๊ฒƒ์— ๋Œ€ํ•œ ๊ฒฝํ—˜์ž์˜ ์กฐ์–ธ์„ ์–ป๋Š”๋ฐ ๋„์›€์„ ์ค๋‹ˆ๋‹ค. + - ์šฐ๋ฆฌ๋Š” ์—ฌ๋Ÿฌ๋ถ„์ด ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์„ ํ•˜๋„๋ก ์„ค๋“ํ•˜๋ ค๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ฉฐ, ์ด๋ฏธ ๊ทธ๋ ‡๊ฒŒ ํ•˜๊ณ ์ž ๊ฒฐ์ •ํ•œ ์‚ฌ๋žŒ๋“ค์„ ๋•๊ณ ์ž ํ•ฉ๋‹ˆ๋‹ค. + - โš ๏ธ ์ด ์น˜ํŠธ์‹œํŠธ๋Š” ์ƒˆ๋กญ๊ฒŒ ๋งŒ๋“ค์–ด์ง„ ์น˜ํŠธ์‹œํŠธ ์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋„์›€์„ ์ฃผ๊ณ ์ž ํ•˜๋Š” ๋ชจ๋“  ๋ถ„๋“ค์„ ํ™˜์˜ํ•ฉ๋‹ˆ๋‹ค. +- [HOC ์น˜ํŠธ์‹œํŠธ(The HOC Cheatsheet)]()๋Š” ์˜ˆ์‹œ์™€ ํ•จ๊ป˜ HOC๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ๋ ค์ค๋‹ˆ๋‹ค. + - [Generics](https://www.typescriptlang.org/docs/handbook/2/generics.html)์— ๋Œ€ํ•œ ์ดํ•ด๊ฐ€ ์„ ํ–‰๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. + - โš ๏ธ ์ด ์น˜ํŠธ์‹œํŠธ๋Š” ์ƒˆ๋กญ๊ฒŒ ๋งŒ๋“ค์–ด์ง„ ์น˜ํŠธ์‹œํŠธ ์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋„์›€์„ ์ฃผ๊ณ ์ž ํ•˜๋Š” ๋ชจ๋“  ๋ถ„๋“ค์„ ํ™˜์˜ํ•ฉ๋‹ˆ๋‹ค. + +--- + +## ๊ธฐ์ดˆ ์น˜ํŠธ์‹œํŠธ (Basic Cheatsheet) + +### ๊ธฐ์ดˆ ์น˜ํŠธ์‹œํŠธ ๋ชฉ์ฐจ From c827fc9cdbd7f3667e370369d0d3e3c559a070e8 Mon Sep 17 00:00:00 2001 From: Seong-Jin Kim Date: Fri, 26 Aug 2022 15:01:03 +0900 Subject: [PATCH 04/25] doc: section1 - setup typescript with react --- README.md | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/README.md b/README.md index c558dae..73b5e69 100644 --- a/README.md +++ b/README.md @@ -49,3 +49,83 @@ TypeScript์— ์ž…๋ฌธํ•˜๋Š” React ๊ฐœ๋ฐœ์ž๋ฅผ ์œ„ํ•œ ์น˜ํŠธ์‹œํŠธ(Cheetsheets) ## ๊ธฐ์ดˆ ์น˜ํŠธ์‹œํŠธ (Basic Cheatsheet) ### ๊ธฐ์ดˆ ์น˜ํŠธ์‹œํŠธ ๋ชฉ์ฐจ + +
+ +๋ชฉ์ฐจ ํ™•์žฅํ•˜๊ธฐ + +- [์„น์…˜ 1: React์— TypeScript ์„ค์ •ํ•˜๊ธฐ]() + + - [์ „์ œ์กฐ๊ฑด]() + +
+ + + +### ์„น์…˜ 1: React์— TypeScript ์„ค์ •ํ•˜๊ธฐ + +#### ์‹œ์ž‘ํ•˜๊ธฐ ์ „ ํ•„์š”ํ•œ ์‚ฌํ•ญ + +1. [React](https://reactjs.org)์— ๋Œ€ํ•œ ์ถฉ๋ถ„ํ•œ ์ดํ•ด +2. [TypeScript Types](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html) ([2ality's guide](http://2ality.com/2018/04/type-notation-typescript.html)๋ฅผ ์•Œ๊ณ ์žˆ์œผ๋ฉด ๋ฌธ์„œ๋ฅผ ์ดํ•ดํ•˜๋Š”๋ฐ ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ TypeScript๋ฅผ ์ฒ˜์Œ ์ ‘ํ•˜๋Š” ๋ถ„์ด๋ผ๋ฉด,[chibicodeโ€™s tutorial](https://ts.chibicode.com/todo/).)๋ฅผ ์ฐธ๊ณ ํ•ด ๋ณด์„ธ์š”. +3. [the TypeScript section in the official React docs](https://reactjs.org/docs/static-type-checking.html#typescript) ์ฝ๊ธฐ +4. [the React section of the new TypeScript playground](http://www.typescriptlang.org/play/index.html?jsx=2&esModuleInterop=true&e=181#example/typescript-with-react) ์ฝ๊ธฐ (์„ ํƒ์‚ฌํ•ญ: [the playground's](http://www.typescriptlang.org/play/index.html) Example Section์˜ 40+ examples ๋‹จ๊ณ„๋ฅผ ์ˆ˜ํ–‰ํ•ด ๋ณด๊ธฐ) + +์ด ๊ฐ€์ด๋“œ๋Š” ๋…์ž๊ฐ€ ๊ฐ€์žฅ ์ตœ์‹  ๋ฒ„์ „์˜ TypeScript์™€ React๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค. ์ด์ „ ๋ฒ„์ „์— ๋Œ€ํ•œ ์‚ฌํ•ญ์€ ํ™•์žฅ ๊ฐ€๋Šฅํ•œ `
` ํƒœ๊ทธ๋กœ ํ™•์ธ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. + +#### VS Code ํ™•์žฅ ํ”„๋กœ๊ทธ๋žจ(Extensions) + +- ๋ฆฌํŽ™ํ† ๋ง ๋ณด์กฐ https://marketplace.visualstudio.com/items?itemName=paulshen.paul-typescript-toolkit +- R+TS Code Snippets (์—ฌ๋Ÿฌ๊ฐ€์ง€ ํ™•์žฅ ํ”„๋กœ๊ทธ๋žจ์ด ์žˆ์Šต๋‹ˆ๋‹ค...) + - https://marketplace.visualstudio.com/items?itemName=infeng.vscode-react-typescript + - https://www.digitalocean.com/community/tutorials/the-best-react-extension-for-vs-code +- TypeScript ๊ณต์‹ ํ™•์žฅํ”„๋กœ๊ทธ๋žจ https://code.visualstudio.com/docs/languages/typescript + +#### React + TypeScript ์ž…๋ฌธ์ž ํ‚คํŠธ + +Cloud setups: + +- [TypeScript Playground with React](https://www.typescriptlang.org/play?#code/JYWwDg9gTgLgBAKjgQwM5wEoFNkGN4BmUEIcA5FDvmQNwCwAUKJLHAN5wCuqWAyjMhhYANFx4BRAgSz44AXzhES5Snhi1GjLAA8W8XBAB2qeAGEInQ0KjjtycABsscALxwAFAEpXAPnaM4OANjeABtA0sYUR4Yc0iAXVcxPgEhdwAGT3oGAOTJaXx3L19-BkDAgBMIXE4QLCsAOhhgGCckgAMATQsgh2BcAGssCrgAEjYIqwVmutR27MC5LM0yuEoYTihDD1zAgB4K4AA3H13yvbAfbs5e-qGRiYspuBmsVD2Aekuz-YAjThgMCMcCMpj6gxcbGKLj8MTiVnck3gAGo4ABGTxyU6rcrlMF3OB1H5wT7-QFGbG4z6HE65ZYMOSMIA)๋Š” ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜์ง€ ์•Š๊ณ  Types๋ฅผ ๋””๋ฒ„๊น…๋งŒ ํ•˜๋Š” ๊ฒฝ์šฐ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +- [CodeSandbox](http://ts.react.new) - cloud IDE, ๋งค์šฐ ๋น ๋ฅธ ๋ถ€ํŒ… ์†๋„๋ฅผ ๊ฐ€์ง‘๋‹ˆ๋‹ค. +- [Stackblitz](https://stackblitz.com/edit/react-typescript-base) - cloud IDE, ๋งค์šฐ ๋น ๋ฅธ ๋ถ€ํŒ… ์†๋„๋ฅผ ๊ฐ€์ง‘๋‹ˆ๋‹ค. + +Local dev setups: + +- [Next.js](https://nextjs.org/docs/basic-features/typescript): `npx create-next-app -e with-typescript` ๋ช…๋ น์–ด๋Š” ์ƒˆ๋กœ์šด NextJS ํ”„๋กœ์ ํŠธ๋ฅผ ํ˜„์žฌ ํด๋”์— ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. +- [Create React App](https://facebook.github.io/create-react-app/docs/adding-typescript): `npx create-react-app name-of-app --template typescript` ๋ช…๋ น์–ด๋Š” ์ƒˆ๋กœ์šด NextJS ํ”„๋กœ์ ํŠธ๋ฅผ ์ƒˆ๋กœ์šด ํด๋”์— ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. +- [Vite](https://vitejs.dev/): `npm create vite@latest my-react-ts-app -- --template react-ts` +- [Meteor](https://guide.meteor.com/build-tool.html#typescript): `meteor create --typescript name-of-my-new-typescript-app` +- [Ignite](https://github.com/infinitered/ignite#use-ignite-andross-infinite-red-andross-boilerplate) for React Native: `ignite new myapp` +- [TSDX](https://tsdx.io/): `npx tsdx create mylib` ๋ช…๋ น์–ด๋Š” React+TS _๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ_ ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. (in future: [TurboRepo](https://twitter.com/jaredpalmer/status/1346217789942591488)) + +
+๋‹ค๋ฅธ ๋„๊ตฌ๋“ค + +์•„์ง ๋ณด์™„์ด ํ•„์š”ํ•˜์ง€๋งŒ ํ™•์ธํ•ด ๋ณผ ๋งŒํ•œ ๊ฐ€์น˜๊ฐ€ ์žˆ๋Š” ๋„๊ตฌ๋“ค: + +- [Snowpack](): `npx create-snowpack-app my-app --template app-template-react-typescript` +- [Docusaurus v2](https://v2.docusaurus.io/docs/installation) with [TypeScript Support](https://v2.docusaurus.io/docs/typescript-support) +- [Parcel](https://v2.parceljs.org/languages/typescript/) +- [JP Morgan's `modular`](https://github.com/jpmorganchase/modular): CRA + TS + Yarn Workspaces toolkit. `yarn create modular-react-app ` + +Manual setup: + +- [Basarat's guide](https://github.com/basarat/typescript-react/tree/master/01%20bootstrap)๋Š” React + TypeScript + Webpack + Babel ์„ **์ˆ˜๋™์œผ๋กœ ์„ค์ •** ํ•  ๊ฒฝ์šฐ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +- ํŠนํžˆ, `@types/react`์™€ `@types/react-dom`๊ฐ€ ์„ค์น˜๋˜์–ด ์žˆ๋Š”์ง€ ํ™•์ธ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ([์ต์ˆ™ํ•˜์ง€ ์•Š์€ ๋‚ด์šฉ์ด๋ผ๋ฉด DefinitelyTyped project ์— ๋Œ€ํ•ด ๋” ์•Œ์•„๋ณด์„ธ์š”.](https://definitelytyped.org/)) +- ๋˜ํ•œ ๋งŽ์€ React + TypeScript bolierplates๋“ค์ด ์žˆ์Šต๋‹ˆ๋‹ค. [์šฐ๋ฆฌ์˜ ๋‹ค๋ฅธ ๋ฆฌ์†Œ์Šค ๋ฆฌ์ŠคํŠธ](https://react-typescript-cheatsheet.netlify.app/docs/basic/recommended/resources/)๋ฅผ ํ™•์ธํ•ด์ฃผ์„ธ์š”. + +
+ +#### ๋น„๋””์˜ค ํŠœํ† ๋ฆฌ์–ผ + +์•„๋ž˜์˜ 7๋ถ€๋กœ ๊ตฌ์„ฑ๋œ "React Typescript Course" ๋น„๋””์˜ค ์‹œ๋ฆฌ์ฆˆ๋ฅผ ํ†ตํ•ด TypeScript with React์— ๋Œ€ํ•œ ์†Œ๊ฐœ๋ฅผ ๋“ค์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + + + react typescript course video series + + + From abb8e4a9d92a9c4e3678e939b585e09309659829 Mon Sep 17 00:00:00 2001 From: Seong-Jin Kim Date: Fri, 26 Aug 2022 19:20:19 +0900 Subject: [PATCH 05/25] doc: 2. getting started - functional components - why is `React.FC` idscouraged? --- README.md | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/README.md b/README.md index 73b5e69..8b04b41 100644 --- a/README.md +++ b/README.md @@ -129,3 +129,60 @@ Manual setup: + +### Section 2: ์‹œ์ž‘ํ•˜๊ธฐ + + + +#### ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ + +ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ๋Š” `props`๋ฅผ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋ฐ›๊ณ  JSX element๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ์ผ๋ฐ˜์ ์ธ ํ•จ์ˆ˜๋กœ ์ž‘์„ฑ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +```tsx +// props์˜ ํƒ€์ž… ์ •์˜ - ๋” ๋งŽ์€ ์˜ˆ์‹œ๋Š” "์ปดํฌ๋„ŒํŠธ Props ํƒ€์ดํ•‘"์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +type AppProps = { + message: string; +}; /* export ํ•œ๋‹ค๋ฉด consumer๊ฐ€ extendํ•  ์ˆ˜ ์žˆ๋„๋ก `interface`๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”. */ + +// ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ€์žฅ ์‰ฌ์šด ๋ฐฉ๋ฒ•; return type์€ ์ถ”๋ก ๋ฉ๋‹ˆ๋‹ค. +const App = ({ message }: AppProps) =>
{message}
; + +// ์‹ค์ˆ˜๋กœ ๋‹ค๋ฅธ ํƒ€์ž…์„ ๋ฐ˜ํ™˜ํ•˜์˜€์„ ๋•Œ ์—๋Ÿฌ๊ฐ€ raise ๋˜๋„๋ก return type์„ ๋ช…์‹œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +const App = ({ message }: AppProps): JSX.Element =>
{message}
; + +// type ์„ ์–ธ์„ ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ ์„ ์–ธ์— ํฌํ•จ์‹œํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.;์ด ๋ฐฉ๋ฒ•์€ prop types์— ์ด๋ฆ„์„ ๋ถ™์ด์ง€ ์•Š์•„๋„ ๋˜์ง€๋งŒ ์ฝ”๋“œ๊ฐ€ ๋ฐ˜๋ณต๋ฉ๋‹ˆ๋‹ค. +const App = ({ message }: { message: string }) =>
{message}
; +``` + +> Tip: type destructure ์„ ์–ธ์„ ์œ„ํ•ด [Paul Shen's VS Code Extension](https://marketplace.visualstudio.com/items?itemName=paulshen.paul-typescript-toolkit)๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ([keyboard shortcut](https://twitter.com/_paulshen/status/1392915279466745857?s=20)์„ ์ถ”๊ฐ€ ํ•˜์„ธ์š”.) + +
+ +React.FC๊ฐ€ ๊ถŒ์žฅ๋˜์ง€ ์•Š๋Š” ์ด์œ ๋Š” ๋ฌด์—‡์ผ๊นŒ์š”? React.FunctionComponent/React.VoidFunctionComponent๋Š” ์–ด๋–ค๊ฐ€์š”? + +React+TypeScript codebases์—์„œ ๋‹ค์Œ ๋ณด์•˜์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +```tsx +const App: React.FunctionComponent<{ message: string }> = ({ message }) =>
{message}
; +``` + +ํ•˜์ง€๋งŒ, ํ˜„์žฌ `React.FunctionComponent` (๋˜๋Š” ๊ฐ„๋žตํ•˜๊ฒŒ ์จ์„œ `React.FC`)๋Š” [๊ถŒ์žฅ๋˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ](https://github.com/facebook/create-react-app/pull/8177)์— ๋Œ€๋ถ€๋ถ„์˜ ์‚ฌ๋žŒ๋“ค์ด ๋™์˜ํ•ฉ๋‹ˆ๋‹ค. ๋ฌผ๋ก  ์ด ์ฃผ์ œ์— ๋Œ€ํ•œ ๋ฏธ๋ฌ˜ํ•œ ์˜๊ฒฌ ์ฐจ์ด๊ฐ€ ์žˆ์„ ์ˆ˜๋Š” ์žˆ์ง€๋งŒ, ๋งŒ์•ฝ ์ด ์˜๊ฒฌ์— ๋™์˜ํ•˜๊ณ  `React.FC`๋ฅผ ๋‹น์‹ ์˜ ์ฝ”๋“œ๋ฒ ์ด์Šค์—์„œ ์ œ๊ฑฐํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด, [์ด jscodeshift codemond](https://github.com/gndelia/codemod-replace-react-fc-typescript)๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +"์ผ๋ฐ˜์ ์ธ ํ•จ์ˆ˜" ๋ฒ„์ „๊ณผ์˜ ์ฐจ์ด์ ๋“ค์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. + +- `React.FunctionComponent`๋Š” return type์„ ๋ช…์‹œ์ ์œผ๋กœ ๋ฐํž™๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ผ๋ฐ˜์ ์ธ ํ•จ์ˆ˜ ๋ฒ„์ „์€ ์•”์‹œ์ ์ž…๋‹ˆ๋‹ค(๋˜๋Š” ์ถ”๊ฐ€์ ์ธ ์–ด๋…ธํ…Œ์ด์…˜(annotation)์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค). + +- `React.FunctionComponent` is explicit about the return type, while the normal function version is implicit (or else needs additional annotation). + +- `displayName`, `propTypes`, ๊ทธ๋ฆฌ๊ณ  `defaultProps`์™€ ๊ฐ™์€ static properties๋ฅผ ์œ„ํ•œ ์ž๋™์™„์„ฑ(autocomplete)๊ณผ ํƒ€์ž… ์ฒดํฌ(Typechecking)๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. + + - `React.FunctionComponent`์™€ ํ•จ๊ป˜ `defaultProps`์„ ์‚ฌ์šฉํ•˜๋Š”๋ฐ ๋ช‡ ๊ฐ€์ง€ ์•Œ๋ ค์ง„ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. [๋ฌธ์ œ์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ](https://github.com/typescript-cheatsheets/react/issues/87)์„ ํ™•์ธํ•˜์„ธ์š”. ์šฐ๋ฆฌ๋Š” ๊ฐœ๋ฐœ์ž๋‹˜์ด ์ฐพ์•„๋ณผ ์ˆ˜ ์žˆ๋Š” ๋ณ„๊ฐœ์˜ `defaultProps` ์„น์…˜์„ ์ œ๊ณตํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. + +- [React 18 type ์—…๋ฐ์ดํŠธ](https://github.com/DefinitelyTyped/DefinitelyTyped/pull/56210) ์ด์ „์—๋Š”, `React.FunctionComponent`์ด `children`์— ๋Œ€ํ•œ ์•”์‹œ์ ์ธ ์ •์˜(implicit definition)๋ฅผ ์ œ๊ณตํ–ˆ์—ˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์—ด๋ค ํ† ๋ก  ๊ณผ์ •์„ ๊ฑฐ์ณค๊ณ  ๊ฒฐ๊ณผ์ ์œผ๋กœ [`React.FC`๊ฐ€ Create React App TypeScript template์—์„œ ์ œ๊ฑฐ](https://github.com/facebook/create-react-app/pull/8177)๋œ ์ด์œ  ์ค‘ ํ•˜๋‚˜๊ฐ€ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. + +```tsx +// React 18 types ์ด์ „ +const Title: React.FunctionComponent<{ title: string }> = ({ children, title }) => ( +
{children}
+); +``` From 715b3ef2419c9cf9c8e7ec0d3a264578b5a758f4 Mon Sep 17 00:00:00 2001 From: Seong-Jin Kim Date: Fri, 26 Aug 2022 19:25:28 +0900 Subject: [PATCH 06/25] fix: Prerequisites --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8b04b41..564ecbd 100644 --- a/README.md +++ b/README.md @@ -67,7 +67,7 @@ TypeScript์— ์ž…๋ฌธํ•˜๋Š” React ๊ฐœ๋ฐœ์ž๋ฅผ ์œ„ํ•œ ์น˜ํŠธ์‹œํŠธ(Cheetsheets) #### ์‹œ์ž‘ํ•˜๊ธฐ ์ „ ํ•„์š”ํ•œ ์‚ฌํ•ญ 1. [React](https://reactjs.org)์— ๋Œ€ํ•œ ์ถฉ๋ถ„ํ•œ ์ดํ•ด -2. [TypeScript Types](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html) ([2ality's guide](http://2ality.com/2018/04/type-notation-typescript.html)๋ฅผ ์•Œ๊ณ ์žˆ์œผ๋ฉด ๋ฌธ์„œ๋ฅผ ์ดํ•ดํ•˜๋Š”๋ฐ ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ TypeScript๋ฅผ ์ฒ˜์Œ ์ ‘ํ•˜๋Š” ๋ถ„์ด๋ผ๋ฉด,[chibicodeโ€™s tutorial](https://ts.chibicode.com/todo/).)๋ฅผ ์ฐธ๊ณ ํ•ด ๋ณด์„ธ์š”. +2. [TypeScript Types](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html)์ฃผ์ œ์— ๋Œ€ํ•œ ์ดํ•ด ([2ality's guide](http://2ality.com/2018/04/type-notation-typescript.html)๋ฅผ ์•Œ๊ณ ์žˆ์œผ๋ฉด ๋ฌธ์„œ๋ฅผ ์ดํ•ดํ•˜๋Š”๋ฐ ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ TypeScript๋ฅผ ์ฒ˜์Œ ์ ‘ํ•˜๋Š” ๋ถ„์ด๋ผ๋ฉด,[chibicodeโ€™s tutorial](https://ts.chibicode.com/todo/)๋ฅผ ์ฐธ๊ณ ํ•ด ๋ณด์„ธ์š”.) 3. [the TypeScript section in the official React docs](https://reactjs.org/docs/static-type-checking.html#typescript) ์ฝ๊ธฐ 4. [the React section of the new TypeScript playground](http://www.typescriptlang.org/play/index.html?jsx=2&esModuleInterop=true&e=181#example/typescript-with-react) ์ฝ๊ธฐ (์„ ํƒ์‚ฌํ•ญ: [the playground's](http://www.typescriptlang.org/play/index.html) Example Section์˜ 40+ examples ๋‹จ๊ณ„๋ฅผ ์ˆ˜ํ–‰ํ•ด ๋ณด๊ธฐ) From 7a708e43e8579cb7826b61d2f62bbaf80d70e8cb Mon Sep 17 00:00:00 2001 From: Seong-Jin Kim Date: Fri, 26 Aug 2022 19:27:45 +0900 Subject: [PATCH 07/25] fix: why is React.FC discouraged? --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index 564ecbd..8953eaf 100644 --- a/README.md +++ b/README.md @@ -172,8 +172,6 @@ const App: React.FunctionComponent<{ message: string }> = ({ message }) =>
- `React.FunctionComponent`๋Š” return type์„ ๋ช…์‹œ์ ์œผ๋กœ ๋ฐํž™๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ผ๋ฐ˜์ ์ธ ํ•จ์ˆ˜ ๋ฒ„์ „์€ ์•”์‹œ์ ์ž…๋‹ˆ๋‹ค(๋˜๋Š” ์ถ”๊ฐ€์ ์ธ ์–ด๋…ธํ…Œ์ด์…˜(annotation)์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค). -- `React.FunctionComponent` is explicit about the return type, while the normal function version is implicit (or else needs additional annotation). - - `displayName`, `propTypes`, ๊ทธ๋ฆฌ๊ณ  `defaultProps`์™€ ๊ฐ™์€ static properties๋ฅผ ์œ„ํ•œ ์ž๋™์™„์„ฑ(autocomplete)๊ณผ ํƒ€์ž… ์ฒดํฌ(Typechecking)๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. - `React.FunctionComponent`์™€ ํ•จ๊ป˜ `defaultProps`์„ ์‚ฌ์šฉํ•˜๋Š”๋ฐ ๋ช‡ ๊ฐ€์ง€ ์•Œ๋ ค์ง„ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. [๋ฌธ์ œ์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ](https://github.com/typescript-cheatsheets/react/issues/87)์„ ํ™•์ธํ•˜์„ธ์š”. ์šฐ๋ฆฌ๋Š” ๊ฐœ๋ฐœ์ž๋‹˜์ด ์ฐพ์•„๋ณผ ์ˆ˜ ์žˆ๋Š” ๋ณ„๊ฐœ์˜ `defaultProps` ์„น์…˜์„ ์ œ๊ณตํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. From 9ab84ab7fd1191f704c84c70f9cbe75f77942d0c Mon Sep 17 00:00:00 2001 From: Seong-Jin Kim Date: Tue, 30 Aug 2022 01:33:43 +0900 Subject: [PATCH 08/25] doc: translate section-function component --- README.md | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/README.md b/README.md index 8953eaf..b9cb336 100644 --- a/README.md +++ b/README.md @@ -184,3 +184,75 @@ const Title: React.FunctionComponent<{ title: string }> = ({ children, title })
{children}
); ``` + +
+(Deprecated)React.VoidFunctionComponent ๋˜๋Š” React.VFC ์‚ฌ์šฉํ•˜๊ธฐ + +[@types/react 16.9.48](https://github.com/DefinitelyTyped/DefinitelyTyped/pull/46643)์—์„œ, `React.VoidFunctionComponent` ๋˜๋Š” `React.VFC` type์€ `children`์„ ๋ช…์‹œ์ ์œผ๋กœ ํƒ€์ดํ•‘(typing) ํ•˜๊ธฐ ์œ„ํ•ด ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค. +ํ•˜์ง€๋งŒ, `React.VFC`์™€ `React.VoidFunctionComponent`๋Š” React 18 (https://github.com/DefinitelyTyped/DefinitelyTyped/pull/59882)์—์„œ ๋”์ด์ƒ ์‚ฌ์šฉ๋˜์ง€ ์•Š๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค(deprecated). ๋”ฐ๋ผ์„œ ์ด ์ž„์‹œ๋ฐฉํŽธ์€ React 18+ ์—์„œ ๋”์ด์ƒ ๊ถŒ์žฅ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. + +์ผ๋ฐ˜์ ์ธ ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ๋‚˜ `React.FC`๋ฅผ ์‚ฌ์šฉํ•ด ์ฃผ์„ธ์š”. + +```ts +type Props = { foo: string }; + +// ์ง€๊ธˆ์€ ๊ดœ์ฐฎ์ง€๋งŒ, ๋ฏธ๋ž˜์—๋Š” ์—๋Ÿฌ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ฌ ๊ฒƒ์ž…๋‹ˆ๋‹ค. +const FunctionComponent: React.FunctionComponent = ({ foo, children }: Props) => { + return ( +
+ {foo} {children} +
+ ); // OK +}; + +// ์ง€๊ธˆ์€ ์—๋Ÿฌ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๊ณ , ๋ฏธ๋ž˜์—๋Š” ๋”์ด์ƒ ์‚ฌ์šฉ๋˜์ง€ ์•Š์„๊ฒƒ์ž…๋‹ˆ๋‹ค.(Deprecated) +const VoidFunctionComponent: React.VoidFunctionComponent = ({ foo, children }) => { + return ( +
+ {foo} + {children} +
+ ); +}; +``` + +
+ +- _๋ฏธ๋ž˜์—๋Š”_, props๋ฅผ ์ž๋™์œผ๋กœ `readonly` ๋ผ๊ณ  ํ‘œ์‹œํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ, props ๊ฐ์ฒด๊ฐ€ ํŒŒ๋ผ๋ฏธํ„ฐ ๋ฆฌ์ŠคํŠธ์—์„œ destructure ๋œ๋‹ค๋ฉด, ์ด๊ฒƒ์€ ์˜๋ฏธ์—†๋Š” ํ–‰๋™ ์ž…๋‹ˆ๋‹ค. + +๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ์—๋Š” ์–ด๋–ค syntax๋ฅผ ์‚ฌ์šฉํ•˜๋˜์ง€ ํฐ ์ฐจ์ด๊ฐ€ ์—†์ง€๋งŒ, `React.FunctionComponent`์˜ ๋ณด๋‹ค ๋ช…์‹œ์ ์ธ ํŠน์„ฑ์„ ์„ ํ˜ธํ•˜๋Š” ๊ฒƒ์ด ์ข‹์„๊ฒƒ์ž…๋‹ˆ๋‹ค. + +
+ +
+์ฃผ์˜ํ•ด์•ผ ํ•  ์‚ฌํ•ญ + +๋‹ค์Œ์˜ ํŒจํ„ด์€ ์ง€์›๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. : + +**์กฐ๊ฑด๋ถ€ ๋ Œ๋”๋ง(conditional rendering)** + +```tsx +const MyConditionalComponent = ({ shouldRender = false }) => (shouldRender ?
: false); // JS ์—์„œ๋„ ์ด๋ ‡๊ฒŒ ํ•˜์ง€ ๋งˆ์‹ญ์‹œ์˜ค. +const el = ; // ์—๋Ÿฌ๋ฅผ throw ํ•ฉ๋‹ˆ๋‹ค. +``` + +์ด ํŒจํ„ด์ด ์ง€์›๋˜์ง€ ์•Š๋Š” ์ด์œ ๋Š” ์ปดํŒŒ์ผ๋Ÿฌ์˜ ํ•œ๊ณ„ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ๋Š” JSX expression ๋˜๋Š” `null` ์ด์™ธ์˜ ๋‹ค๋ฅธ ์–ด๋–ค ๊ฒƒ๋„ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์—†๋Š” ๊ฒƒ์ด ๋ฐ˜ํ™˜๋œ๋‹ค๋ฉด ํ•ด๋‹น ํƒ€์ž…์€ `Element`์— ํ• ๋‹น๋  ์ˆ˜ ์—†๋‹ค๋Š” ์—๋Ÿฌ ๋ฉ”์„ธ์ง€๋ฅผ ๋ณด๊ฒŒ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ("{the other type} is not assignable to `Element`.") + +**Array.fill** + +```tsx +const MyArrayComponent = () => Array(5).fill(
); +const el2 = ; // throws an error +``` + +์•„์‰ฝ๊ฒŒ๋„ ํ•จ์ˆ˜์˜ ํƒ€์ž…์„ annotate ํ•˜๋Š” ๊ฒƒ์€ ์•„๋ฌด๋Ÿฐ ๋„์›€์ด ๋˜์ง€ ์•Š์„๊ฒƒ์ž…๋‹ˆ๋‹ค. React๊ฐ€ ์ง€์›ํ•˜๋Š” ๋‹ค๋ฅธ ํŠน๋ณ„ํ•œ ํƒ€์ž…(exotic type)์„ ๋ฐ˜ํ™˜ํ•˜๊ณ ์ž ํ•œ๋‹ค๋ฉด ํƒ€์ž… ํ‘œ๋ช…(type assertion)์„ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. : + +```tsx +const MyArrayComponent = () => Array(5).fill(
) as any as JSX.Element; +``` + +[์—ฌ๊ธฐ์„œ @ferdaber ์˜ ์„ค๋ช…์„ ํ™•์ธํ•ด๋ณด์„ธ์š”](https://github.com/typescript-cheatsheets/react/issues/57). + +
+ + From e8df0da1cfbc63eb6f919f4f64a7721ab2b6d7b4 Mon Sep 17 00:00:00 2001 From: Seong-Jin Kim Date: Tue, 30 Aug 2022 01:39:36 +0900 Subject: [PATCH 09/25] fix: typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b9cb336..287524f 100644 --- a/README.md +++ b/README.md @@ -189,7 +189,7 @@ const Title: React.FunctionComponent<{ title: string }> = ({ children, title }) (Deprecated)React.VoidFunctionComponent ๋˜๋Š” React.VFC ์‚ฌ์šฉํ•˜๊ธฐ [@types/react 16.9.48](https://github.com/DefinitelyTyped/DefinitelyTyped/pull/46643)์—์„œ, `React.VoidFunctionComponent` ๋˜๋Š” `React.VFC` type์€ `children`์„ ๋ช…์‹œ์ ์œผ๋กœ ํƒ€์ดํ•‘(typing) ํ•˜๊ธฐ ์œ„ํ•ด ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค. -ํ•˜์ง€๋งŒ, `React.VFC`์™€ `React.VoidFunctionComponent`๋Š” React 18 (https://github.com/DefinitelyTyped/DefinitelyTyped/pull/59882)์—์„œ ๋”์ด์ƒ ์‚ฌ์šฉ๋˜์ง€ ์•Š๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค(deprecated). ๋”ฐ๋ผ์„œ ์ด ์ž„์‹œ๋ฐฉํŽธ์€ React 18+ ์—์„œ ๋”์ด์ƒ ๊ถŒ์žฅ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. +ํ•˜์ง€๋งŒ, `React.VFC`์™€ `React.VoidFunctionComponent`๋Š” React 18 (https://github.com/DefinitelyTyped/DefinitelyTyped/pull/59882) ์—์„œ ๋”์ด์ƒ ์‚ฌ์šฉ๋˜์ง€ ์•Š๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค(deprecated). ๋”ฐ๋ผ์„œ ์ด ์ž„์‹œ๋ฐฉํŽธ์€ React 18+ ์—์„œ ๋”์ด์ƒ ๊ถŒ์žฅ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์ธ ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ๋‚˜ `React.FC`๋ฅผ ์‚ฌ์šฉํ•ด ์ฃผ์„ธ์š”. From 8cd09ae9088c7ea29f60a16776e183f3b18284b0 Mon Sep 17 00:00:00 2001 From: Seong-Jin Kim Date: Sun, 4 Sep 2022 05:07:06 +0900 Subject: [PATCH 10/25] =?UTF-8?q?doc:=20useState,=20useReducer=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) diff --git a/README.md b/README.md index 287524f..d3b7a69 100644 --- a/README.md +++ b/README.md @@ -256,3 +256,93 @@ const MyArrayComponent = () => Array(5).fill(
) as any as JSX.Element;
+ + + +#### Hooks + +Hook์€ [`@types/react` v16.8 ์ด์ƒ๋ถ€ํ„ฐ ์ง€์›๋ฉ๋‹ˆ๋‹ค](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/a05cc538a42243c632f054e42eab483ebf1560ab/types/react/index.d.ts#L800-L1031). + +#### useState + +ํƒ€์ž… ์ถ”๋ก (Type inference)์€ ๊ฐ„๋‹จํ•œ ๊ฐ’๋“ค์— ์ž˜ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค: + +```tsx +const [state, setState] = useState(false); +// `state` ๋Š” boolean ์œผ๋กœ ์ถ”๋ก ๋ฉ๋‹ˆ๋‹ค. +// `setState` ๋Š” boolean ๊ฐ’ ๋งŒ์„ ๋ฐ›์Šต๋‹ˆ๋‹ค. +``` + +ํƒ€์ž… ์ถ”๋ก ์— ๋ณต์žกํ•œ ํƒ€์ž…์„ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค๋ฉด [์ถ”๋ก ๋œ ํƒ€์ž…(Inferred Types) ์‚ฌ์šฉํ•˜๊ธฐ](https://react-typescript-cheatsheet.netlify.app/docs/basic/troubleshooting/types/#using-inferred-types) ๋„ ํ™•์ธํ•ด๋ณด์„ธ์š”. + +ํ•˜์ง€๋งŒ ๋งŽ์€ hook ๋“ค์€ null ๊ฐ™์€ ๊ฐ’๋ฅผ ๋””ํดํŠธ ๊ฐ’์œผ๋กœ ์ดˆ๊ธฐํ™” ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์–ด๋–ป๊ฒŒ ํƒ€์ž…์„ ์ง€์ •ํ•˜๋Š”์ง€ ๊ถ๊ธˆํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ช…์‹œ์ ์œผ๋กœ ํƒ€์ž…์„ ์„ ์–ธํ•˜๊ณ , union type์„ ์‚ฌ์šฉํ•˜์„ธ์š”.: + +```tsx +const [user, setUser] = useState(null); + +// later... +setUser(newUser); +``` + +๋งŒ์•ฝ useState์„ค์ • ์งํ›„์— state๊ฐ€ ์ดˆ๊ธฐํ™”๋˜๊ณ  ๊ทธ ์ดํ›„์— ํ•ญ์ƒ ๊ฐ’์„ ๊ฐ€์ง„๋‹ค๋ฉด, ํƒ€์ž… ํ‘œ๋ช…(type assertions)์„ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. + +```tsx +const [user, setUser] = useState({} as User); + +// later... +setUser(newUser); +``` + +์ด ๋ฐฉ๋ฒ•์€ ์ผ์‹œ์ ์œผ๋กœ ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ ์ปดํŒŒ์ผ๋Ÿฌ์—๊ฒŒ `{}`๊ฐ€ `User`์˜ type์ด๋ผ๊ณ  "๊ฑฐ์ง“๋ง" ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ ํ›„์— `user` state๋ฅผ ์„ค์ •ํ•˜์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ๋‚˜๋จธ์ง€ ์ฝ”๋“œ๊ฐ€ `user`๋Š” `User` ํƒ€์ž…์ด๋ผ๋Š” ์‚ฌ์‹ค์— ์˜์กด๊ณ  ์ด๊ฒƒ์€ ๋Ÿฐํƒ€์ž… ์—๋Ÿฌ๋กœ ์ด์–ด์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +#### useReducer + +Reducer actions๋ฅผ ์œ„ํ•ด [Discriminated Unions](https://www.typescriptlang.org/docs/handbook/typescript-in-5-minutes-func.html#discriminated-unions)๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. reducer์˜ return type์„ ์ •์˜ํ•˜๋Š” ๊ฒƒ์„ ์žŠ์ง€ ๋งˆ์„ธ์š”. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ๊ฐ€ return type์„ ์ถ”๋ก ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. + +```tsx +import { useReducer } from "react"; + +const initialState = { count: 0 }; + +type ACTIONTYPE = { type: "increment"; payload: number } | { type: "decrement"; payload: string }; + +function reducer(state: typeof initialState, action: ACTIONTYPE) { + switch (action.type) { + case "increment": + return { count: state.count + action.payload }; + case "decrement": + return { count: state.count - Number(action.payload) }; + default: + throw new Error(); + } +} + +function Counter() { + const [state, dispatch] = useReducer(reducer, initialState); + return ( + <> + Count: {state.count} + + + + ); +} +``` + +[TypeScript Playground์—์„œ ๋ณด๊ธฐ](https://www.typescriptlang.org/play?#code/LAKFEsFsAcHsCcAuACAVMghgZ2QJQKYYDGKAZvLJMgOTyEnUDcooRsAdliuO+IuBgA2AZUQZE+ZAF5kAbzYBXdogBcyAAwBfZmBCIAntEkBBAMIAVAJIB5AHLmAmgAUAotOShkyAD5zkBozVqHiI6SHxlagAaZGgMfUFYDAATNXYFSAAjfHhNDxAvX1l-Q3wg5PxQ-HDImLiEpNTkLngeAHM8ll1SJRJwDmQ6ZIUiHIAKLnEykqNYUmQePgERMQkY4n4ONTMrO0dXAEo5T2aAdz4iAAtkMY3+9gA6APwj2ROvImxJYPYqmsRqCp3l5BvhEAp4Ow5IplGpJhIHjCUABqTB9DgPeqJFLaYGfLDfCp-CIAoEFEFeOjgyHQ2BKVTNVb4RF05TIAC0yFsGWy8Fu6MeWMaB1x5K8FVIGAUglUwK8iEuFFOyHY+GVLngFD5Bx0Xk0oH13V6myhplZEm1x3JbE4KAA2vD8DFkuAsHFEFcALruAgbB4KAkEYajPlDEY5GKLfhCURTHUnKkQqFjYEAHgAfHLkGb6WpZI6WfTDRSvKnMgpEIgBhxTIJwEQANZSWRjI5SdPIF1u8RXMayZ7lSphEnRWLxbFNagAVmomhF6fZqYA9OXKxxM2KQWWK1WoTW643m63pB2u+7e-3SkEQsPamOGik1FO55p08jl6vdxuKcvv8h4yAmhAA) + +
+ +Redux์—์„œ Reducer์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๊ธฐ + +Reducer funciton์„ ์ž‘์„ฑํ•˜๊ธฐ ์œ„ํ•ด [redux](https://github.com/reduxjs/redux)๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ, return type์„ ์ฒ˜๋ฆฌํ•˜๋Š” `Reducer` ํ˜•์‹์˜ ํŽธ๋ฆฌํ•œ helper๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +์œ„์˜ reducer example์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ฐ”๋€” ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. : + +```tsx +import { Reducer } from 'redux'; + +export function reducer: Reducer() {} +``` + +
From f3934835bdf9d5225ff78894ef38d8ee891fc5ff Mon Sep 17 00:00:00 2001 From: Seong-Jin Kim Date: Thu, 8 Sep 2022 01:57:38 +0900 Subject: [PATCH 11/25] doc: translate useEffect / useLayoutEffect --- README.md | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/README.md b/README.md index d3b7a69..c9a1349 100644 --- a/README.md +++ b/README.md @@ -346,3 +346,43 @@ export function reducer: Reducer() {} ``` + +#### useEffect / useLayoutEffect + +`userEffect`์™€ `userLayoutEffect` ๋‘˜ ๋‹ค side effect๋ฅผ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋˜๊ณ  ์„ ํƒ์ ์œผ๋กœ cleanup function์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋งŒ์•ฝ ์ด hook๋“ค์ด ๋ฐ˜ํ™˜ ๊ฐ’์„ ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด, type์ด ํ•„์š” ์—†๋‹ค๋Š” ๋œป์ž…๋‹ˆ๋‹ค. `useEffect`๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ, ํ•จ์ˆ˜ ๋˜๋Š” `undefined` ์ด์™ธ์˜ ๋‹ค๋ฅธ ๊ฒƒ์„ ๋ฐ˜ํ™˜ํ•˜์ง€ ์•Š๋„๋ก ์ฃผ์˜ํ•˜์„ธ์š”. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด TypeScript์™€ React๋Š” ๋‹น์‹ ์—๊ฒŒ ๋น„๋ช…์„ ์ง€๋ฅผ๊ฒƒ์ž…๋‹ˆ๋‹ค. Arros functions๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ์ด ๋ฌธ์ œ๋Š” ๋‹ค์†Œ ํŒŒ์•…ํ•˜๊ธฐ ์–ด๋ ค์šธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. : + +```ts +function DelayedEffect(props: { timerMs: number }) { + const { timerMs } = props; + + useEffect( + () => + setTimeout(() => { + /* do stuff */ + }, timerMs), + [timerMs] + ); + // ๋‚˜์œ ์˜ˆ์‹œ! setTimeout์€ ์•”๋ฌต์ ์œผ๋กœ ์ˆซ์ž๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. + // arrow function์˜ body๊ฐ€ ์ค‘๊ด„ํ˜ธ๋กœ ๊ฐ์‹ธ์ง€์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. + return null; +} +``` + +
+์œ„ ์˜ˆ์‹œ์— ๋Œ€ํ•œ ํ•ด๊ฒฐ์ฑ… + +```tsx +function DelayedEffect(props: { timerMs: number }) { + const { timerMs } = props; + + useEffect(() => { + setTimeout(() => { + /* do stuff */ + }, timerMs); + }, [timerMs]); + // ๋” ๋‚˜์€ ๋ฐฉ๋ฒ•; ํ™•์‹คํ•˜๊ฒŒ undefined๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ธฐ ์œ„ํ•ด์„œ void keyword๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”. + return null; +} +``` + +
From 912d856eec2836b7d5399c4f465e2d3896df2b44 Mon Sep 17 00:00:00 2001 From: Seong-Jin Kim Date: Thu, 8 Sep 2022 02:22:21 +0900 Subject: [PATCH 12/25] doc: translate useRef --- README.md | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/README.md b/README.md index c9a1349..7b3e607 100644 --- a/README.md +++ b/README.md @@ -386,3 +386,77 @@ function DelayedEffect(props: { timerMs: number }) { ``` + +#### useRef + +TypeScript์—์„œ `useRef`๋Š” type argument๊ฐ€ ์ดˆ๊ธฐ ๊ฐ’์„ ์™„์ „ํžˆ ํฌํ•จ(cover)ํ•˜๋Š”์ง€ ์•„๋‹Œ์ง€์— ๋”ฐ๋ผ[read-only](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/abd69803c1b710db58d511f4544ec1b70bc9077c/types/react/v16/index.d.ts#L1025-L1039)๋˜๋Š” [mutable](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/abd69803c1b710db58d511f4544ec1b70bc9077c/types/react/v16/index.d.ts#L1012-L1023) ๋‘˜ ์ค‘ ํ•˜๋‚˜๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๊ฐ์ž์˜ use case์— ๋งž๋Š” ๊ฒƒ์„ ์„ ํƒํ•˜์„ธ์š”. + +##### Option 1: DOM element ref + +**[DOM element์— ์ ‘๊ทผํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š”](https://reactjs.org/docs/refs-and-the-dom.html):** element type ๋งŒ์„ argument๋กœ ๋„˜๊ฒจ์ฃผ๊ณ  `null`์„ ์ดˆ๊ธฐ ๊ฐ’์œผ๋กœ ์‚ฌ์šฉํ•˜์„ธ์š”. ์ด ๊ฒฝ์šฐ์—, ๋ฐ˜ํ™˜๋˜๋Š” reference๋Š” React์— ์˜ํ•ด ๊ด€๋ฆฌ๋˜๋Š” read-only `.current`๋ฅผ ๊ฐ€์งˆ ๊ฒƒ์ž…๋‹ˆ๋‹ค. TypeScript๋Š” ์ด ref๋ฅผ element์˜ `ref` prop์œผ๋กœ ์ „๋‹ฌ ๋ฐ›๊ธฐ๋ฅผ ๊ธฐ๋Œ€ํ•ฉ๋‹ˆ๋‹ค. : + +```tsx +function Foo() { + // - ๊ฐ€๋Šฅํ•œ ์ƒ์„ธํ•˜๊ฒŒ ์ž‘์„ฑํ•˜์„ธ์š”. ์˜ˆ๋ฅผ๋“ค๋ฉด, HTMLDivElement๋Š” HTMLElement๋ณด๋‹ค ๋” ์ข‹๊ณ , + // Element๋ณด๋‹ค๋Š” ํ›จ์‹  ๋” ์ข‹์€ ์„ ํƒ์ž…๋‹ˆ๋‹ค. + // - ๊ธฐ์ˆ ์ ์œผ๋กœ ๋งํ•˜์ž๋ฉด, ์ด๊ฒƒ์€ RefObject๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. + const divRef = useRef(null); + + useEffect(() => { + // ref.current๊ฐ€ null์ผ ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์ฃผ์˜ํ•˜์„ธ์š”. + // ์ด๊ฒƒ์€ ๋‹น์‹ ์ด ์กฐ๊ฑด์— ๋”ฐ๋ผ์„œ ref๋œ(ref-ed) element๋ฅผ renderํ•˜๊ฑฐ๋‚˜ + // ํ• ๋‹นํ•˜๋Š” ๊ฒƒ์„ ์žŠ์„ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์˜ˆ์ธกํ•  ์ˆ˜ ์žˆ๋Š” ํ˜„์ƒ์ž…๋‹ˆ๋‹ค. + if (!divRef.current) throw Error("divRef is not assigned"); + + // ์ด์ œ divRef.current๋Š” ํ™•์‹คํ•˜๊ฒŒ HTMLDivElement ์ž…๋‹ˆ๋‹ค. + doSomethingWith(divRef.current); + }); + + // React๊ฐ€ ๋‹น์‹ ์„ ์œ„ํ•ด ref๋ฅผ ๊ด€๋ฆฌํ•  ์ˆ˜์žˆ๋„๋ก element์—๊ฒŒ ref๋ฅผ ์ „๋‹ฌํ•ด ์ฃผ์„ธ์š”. + return
etc
; +} +``` + +๋งŒ์•ฝ `divRef.current`๊ฐ€ ์ ˆ๋Œ€๋กœ null์ด ์•„๋‹๊ฒƒ์ด๋ผ๋Š” ๊ฒƒ์„ ํ™•์‹ ํ•œ๋‹ค๋ฉด, non-null assertion operator `!`์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. : + +```tsx +const divRef = useRef(null!); +// ๋‚˜์ค‘์—... ์ด๊ฒƒ์ด null ์ธ์ง€ ํ™•์ธํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. +doSomethingWith(divRef.current); +``` + +๋‹น์‹ ์ด type safety๊ฐ€ ๋ณด์žฅ๋œ๋‹ค๊ณ  ๋ฏธ๋ฆฌ ๊ฐ€์ •ํ•˜๊ณ  ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•œ๋‹ค๋Š” ๊ฒƒ์— ์ฃผ์˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋ Œ๋”๋ง ๊ณผ์ •์—์„œ ref๋ฅผ element์— ํ• ๋‹นํ•˜๋Š” ๊ฒƒ์„ ์žŠ๊ฑฐ๋‚˜, ref๋œ(ref-ed) element๊ฐ€ ์กฐ๊ฑด๋ถ€ ๋ Œ๋”๋ง ๋œ๋‹ค๋ฉด runtime error๊ฐ€ ๋ฐœ์ƒํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. + +
+Tip: ์–ด๋–ค HTMLElement๋ฅผ ์‚ฌ์šฉํ• ์ง€ ์„ ํƒํ•˜๊ธฐ + +Ref๋Š” ๋ช…์‹œ์„ฑ(specificity)์„ ํ•„์š”๋กœ ํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰, `HTMLElement` ๋งŒ์„ ๋ช…์‹œํ•˜๋Š” ๊ฒƒ์€ ์ถฉ๋ถ„ํ•˜์ง€ ์•Š๋‹ค๋Š” ๋ง์ž…๋‹ˆ๋‹ค. ๋งŒ์•ฝ ๋‹น์‹ ์ด ํ•„์š”ํ•œ element type์˜ ์ด๋ฆ„์„ ๋ชจ๋ฅธ๋‹ค๋ฉด, [lib.dom.ts](https://github.com/microsoft/TypeScript/blob/v3.9.5/lib/lib.dom.d.ts#L19224-L19343)์—์„œ ํ™•์ธํ•˜๊ฑฐ๋‚˜ ์˜๋„์ ์œผ๋กœ type error๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๊ณ  language service๊ฐ€ type์˜ ์ด๋ฆ„์„ ์•Œ๋ ค์ฃผ๋„๋ก ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +![image](https://user-images.githubusercontent.com/6764957/116914284-1c436380-ac7d-11eb-9150-f52c571c5f07.png) + +
+ +##### Option 2: Mutable value ref + +**[mutable value๋ฅผ ๊ฐ€์ง€๊ธฐ ์œ„ํ•ด์„œ๋Š”](https://reactjs.org/docs/hooks-faq.html#is-there-something-like-instance-variables):** ์›ํ•˜๋Š” type์„ ์‚ฌ์šฉํ•˜๊ณ  ์ดˆ๊ธฐ ๊ฐ’์ด ์™„์ „ํžˆ ํ•ด๋‹น type์— ์†ํ•˜๋Š”์ง€ ํ™•์ธํ•˜์„ธ์š”. + +```tsx +function Foo() { + // ๊ธฐ์ˆ ์ ์œผ๋กœ ๋งํ•˜์ž๋ฉด, ์ด๊ฒƒ์€ MutableRefObject์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. + const intervalRef = useRef(null); + + // ๋‹น์‹ ์ด ์ง์ ‘ ref๋ฅผ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค. (์ด๊ฒƒ์ด MutableRefObject๋ผ๊ณ  ๋ถˆ๋ฆฌ๋Š” ์ด์œ ์ด์ฃ .) + useEffect(() => { + intervalRef.current = setInterval(...); + return () => clearInterval(intervalRef.current); + }, []); + + // ref๋Š” element์˜ "ref" prop์œผ๋กœ ์ „๋‹ฌ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. + return ; +} +``` + +##### ๋‹ค์Œ์˜ ์ž๋ฃŒ๋„ ํ™•์ธํ•ด ๋ณด์„ธ์š”. + +- [@rajivpunjabi๊ฐ€ ์ž‘์„ฑํ•œ ๊ด€๋ จ ์ด์Šˆ](https://github.com/typescript-cheatsheets/react/issues/388) - [Playground](https://www.typescriptlang.org/play#code/JYWwDg9gTgLgBAKjgQwM5wEoFNkGN4BmUEIcARFDvmQNwCwAUI7hAHarwCCYYcAvHAAUASn4A+OAG9GjOHAD0CBLLnKGcxHABiwKBzgQwMYGxS4WUACbBWAczgwIcSxFwBXEFlYxkxtgDoVTQBJVmBjZAAbOAA3KLcsOAB3YEjogCNE1jc0-zgAGQBPG3tHOAAVQrAsAGVcKGAjOHTCuDdUErhWNgBabLSUVFQsWBNWA2qoX2hA9VU4AGFKXyx0AFk3H3TIxOwCOAB5dIArLHwgpHcoSm84MGJJmFbgdG74ZcsDVkjC2Y01f7yFQsdjvLAEACM-EwVBg-naWD2AB4ABLlNb5GpgZCsACiO083jEgn6kQAhMJ6HMQfpKJCFpE2IkBNg8HCEci0RisTj8VhCTBiaSKVSVIoAaoLnBQuFgFFYvFEikBpkujkMps4FgAB7VfCdLmY7F4gleOFwAByEHg7U63VYfXVg2Go1MhhG0ygf3mAHVUtF6jgYLtwUdTvguta4Bstjs9mGznCpVcbvB7u7YM90B8vj9vYgLkDqWxaeCAEzQ1n4eHDTnoo2801EknqykyObii5SmpnNifA5GMZmCzWOwOJwudwC3xjKUyiLROKRBLJf3NLJO9KanV64xj0koVifQ08k38s1Sv0DJZBxIx5DbRGhk6J5Nua5mu4PEZPOAvSNgsgnxsHmXZzIgRZyDSYIEAAzJWsI1k+BCovWp58gKcAAD5qmkQqtqKHbyCexoYRecw7IQugcAs76ptCdIQv4KZmoRcjyMRaGkU28A4aSKiUXAwwgpYtEfrcAh0mWzF0ax7bsZx3Lceetx8eqAlYPAMAABa6KJskSXAdKwTJ4kwGxCjyKy-bfK05SrDA8mWVagHAbZeScOY0CjqUE6uOgqDaRAOSfKqOYgb8KiMaZ9GSeCEIMkyMVyUwRHWYc7nSvAgUQEk6AjMQXpReWyWGdFLHeBZHEuTCQEZT8xVwaV8BxZCzUWZQMDvuMghBHASJVnCWhTLYApiH1chIqgxpGeCfCSIxAC+Yj3o+8YvvgSLyNNOLjeBGhTTNdLzVJy3reGMBbTtrB7RoB3XbNBAneCsHLatcbPhdV3GrdB1WYhw3IKNZq-W2DCLYRO7QPAljgsgORcDwVJAA) +- [Stefan Baumgartner์˜ ์˜ˆ์‹œ](https://fettblog.eu/typescript-react/hooks/#useref) - [Playground](https://www.typescriptlang.org/play/?jsx=2#code/JYWwDg9gTgLgBAJQKYEMDG8BmUIjgIilQ3wFgAoCzAVwDsNgJa4AVJADxgElaxqYA6sBgALAGIQ01AM4AhfjCYAKAJRwA3hThwA9DrjBaw4CgA2waUjgB3YSLi1qp0wBo4AI35wYSZ6wCeYEgAymhQwGDw1lYoRHCmEBAA1oYA5nCY0HAozAASLACyADI8fDAAoqZIIEi0MFpwaEzS8IZllXAAvIjEMAB0MkjImAA8+cWl-JXVtTAAfEqOzioA3A1NtC1wTPIwirQAwuZoSV1wql1zGg3aenAt4RgOTqaNIkgn0g5ISAAmcDJvBA3h9TsBMAZeFNXjl-lIoEQ6nAOBZ+jddPpPPAmGgrPDEfAUS1pG5hAYvhAITBAlZxiUoRUqjU6m5RIDhOi7iIUF9RFYaqIIP9MlJpABCOCAUHJ0eDzm1oXAAGSKyHtUx9fGzNSacjaPWq6Ea6gI2Z9EUyVRrXV6gC+DRtVu0RBgxuYSnRIzm6O06h0ACpIdlfr9jExSQyOkxTP5GjkPFZBv9bKIDYSmbNpH04ABNFD+CV+nR2636kby+BETCddTlyo27w0zr4HycfC6L0lvUjLH7baHY5Jas7BRMI7AE42uYSUXed6pkY6HtMDulnQruCrCg2oA) From 26bbc62a4cf2f35264179a4ef06b859e84ce258e Mon Sep 17 00:00:00 2001 From: Seong-Jin Kim Date: Wed, 24 Aug 2022 05:55:46 +0900 Subject: [PATCH 13/25] doc: basic cheatsheets --- README.md | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index f0db150..1c6c467 100644 --- a/README.md +++ b/README.md @@ -1 +1,38 @@ -# react-typescript-cheatsheet-kr \ No newline at end of file +# React+TypeScript Cheatsheets ํ•œ๊ตญ์–ดํŒ ๐Ÿ‡ฐ๐Ÿ‡ท + +TypeScript์— ์ž…๋ฌธํ•˜๋Š” React ๊ฐœ๋ฐœ์ž๋ฅผ ์œ„ํ•œ ์น˜ํŠธ์‹œํŠธ(Cheetsheets) + +--- + + + react + ts logo + + +[**์›น ๋‹คํ๋จผํŠธ**](https://react-typescript-cheatsheet.netlify.app/docs/basic/setup) | +[**์˜์–ดํŒ**](https://github.com/typescript-cheatsheets/react-typescript-cheatsheet-es) | +[ํ”„๋กœ์ ํŠธ์— ๊ธฐ์—ฌํ•˜๊ธฐ]() | +[์งˆ๋ฌธํ•˜๊ธฐ]() + +:wave: ๋ณธ ๋ฆฌํฌ์ง€ํ† ๋ฆฌ๋Š” [@ryan_kim_kr](https://twitter.com/ryan_kim_kr)์— ์˜ํ•ด ๊ด€๋ฆฌ๋˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐœ๋ฐœ์ž๋‹˜์ด React์™€ ํ•จ๊ป˜ TypeScript๋ฅผ ์‚ฌ์šฉํ•ด๋ณด๊ณ ์ž ํ•˜์‹œ๋‹ค๋‹ˆ ์ •๋ง ๊ธฐ์œ ์†Œ์‹์ด๊ตฐ์š”! ์ž˜๋ชป๋œ ๋ถ€๋ถ„์ด ๋ฐœ๊ฒฌ๋˜์–ด ์ˆ˜์ •์ด ํ•„์š”ํ•˜๊ฑฐ๋‚˜ ๋ˆ„๋ฝ๋œ ๋ถ€๋ถ„์ด ์žˆ๋‹ค๋ฉด ๊ฐœ์„  ๋˜์–ด์•ผ ํ•  ์‚ฌํ•ญ์„ [์ด์Šˆ ๋“ฑ๋ก](https://github.com/typescript-cheatsheets/react-typescript-cheatsheet-kr/issues/new)ํ•ด ์ฃผ์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค. :+1: + +--- + +[![All Contributors](https://img.shields.io/github/contributors/typescript-cheatsheets/react-typescript-cheatsheet?color=orange&style=flat-square)](/COLABORADORES.md) + +# All React + TypeScript Cheatsheets + +- [๊ธฐ์ดˆ ์น˜ํŠธ์‹œํŠธ]()๋Š” React ๊ฐœ๋ฐœ์ž๊ฐ€ React app์—์„œ TS ์‚ฌ์šฉ์„ ์‹œ์ž‘ํ•˜๋Š” ๊ฒƒ์— ๋„์›€์„ ์ฃผ๊ธฐ ์œ„ํ•œ ๋‚ด์šฉ์ด ์ฃผ๋ฅผ ์ด๋ฃน๋‹ˆ๋‹ค. + - ๋ชจ๋ฒ” ์‚ฌ๋ก€(Best Practices)๋ผ๊ณ  ์—ฌ๊ฒจ์ง€๋Š”, ๋ณต์‚ฌ + ๋ถ™์—ฌ๋„ฃ๊ธฐ ๊ฐ€๋Šฅํ•œ ์˜ˆ์‹œ + - ๊ธฐ๋ณธ์ ์ธ TS Types ์‚ฌ์šฉ๋ฒ•๊ณผ ์„ค์ • ๋ฐฉ๋ฒ• + - ์ž์ฃผ ๋ฌป๋Š” ์งˆ๋ฌธ(FAQ)์— ๋Œ€ํ•œ ๋‹ต๋ณ€ + - Generic type logic์€ ๊นŠ์ด ๋‹ค๋ฃจ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ ๋Œ€์‹ , ์ดˆ์‹ฌ์ž๋“ค์„ ์œ„ํ•ด ๊ฐ„๋‹จํ•œ ํŠธ๋Ÿฌ๋ธ”์ŠˆํŒ… ๊ธฐ์ˆ ๋“ค์„ ์†Œ๊ฐœํ•ฉ๋‹ˆ๋‹ค. + - ๊ธฐ์ดˆ ์น˜ํŠธ์‹œํŠธ์˜ ๋ชฉ์ ์€ ๊ฐœ๋ฐœ์ž๊ฐ€ TypeScript์— ๋Œ€ํ•ด ๋„ˆ๋ฌด ๋งŽ์€ ๊ณต๋ถ€๋ฅผ ํ•˜์ง€ ์•Š๊ณ ์„œ๋„ **์‹œ๊ฐ„ ํšจ์œจ์ **์œผ๋กœ React ๊ฐœ๋ฐœ์— TypeScript๋ฅผ ๋น ๋ฅด๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๋•๊ธฐ ์œ„ํ•ฉ๋‹ˆ๋‹ค. +- [๊ณ ๊ธ‰ ์น˜ํŠธ์‹œํŠธ]() +- [๋งˆ์ด๊ทธ๋ ˆ์ดํŒ… ์น˜ํŠธ์‹œํŠธ]() +- [HOC ์น˜ํŠธ์‹œํŠธ]() From 62aa968061cae16860913bfb509ae0e79728e08c Mon Sep 17 00:00:00 2001 From: Seong-Jin Kim Date: Wed, 24 Aug 2022 16:09:36 +0900 Subject: [PATCH 14/25] doc: translate The Adcanced Cheatsheet --- README.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 1c6c467..a5e9390 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,10 @@ TypeScript์— ์ž…๋ฌธํ•˜๋Š” React ๊ฐœ๋ฐœ์ž๋ฅผ ์œ„ํ•œ ์น˜ํŠธ์‹œํŠธ(Cheetsheets) - ๊ธฐ๋ณธ์ ์ธ TS Types ์‚ฌ์šฉ๋ฒ•๊ณผ ์„ค์ • ๋ฐฉ๋ฒ• - ์ž์ฃผ ๋ฌป๋Š” ์งˆ๋ฌธ(FAQ)์— ๋Œ€ํ•œ ๋‹ต๋ณ€ - Generic type logic์€ ๊นŠ์ด ๋‹ค๋ฃจ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ ๋Œ€์‹ , ์ดˆ์‹ฌ์ž๋“ค์„ ์œ„ํ•ด ๊ฐ„๋‹จํ•œ ํŠธ๋Ÿฌ๋ธ”์ŠˆํŒ… ๊ธฐ์ˆ ๋“ค์„ ์†Œ๊ฐœํ•ฉ๋‹ˆ๋‹ค. - - ๊ธฐ์ดˆ ์น˜ํŠธ์‹œํŠธ์˜ ๋ชฉ์ ์€ ๊ฐœ๋ฐœ์ž๊ฐ€ TypeScript์— ๋Œ€ํ•ด ๋„ˆ๋ฌด ๋งŽ์€ ๊ณต๋ถ€๋ฅผ ํ•˜์ง€ ์•Š๊ณ ์„œ๋„ **์‹œ๊ฐ„ ํšจ์œจ์ **์œผ๋กœ React ๊ฐœ๋ฐœ์— TypeScript๋ฅผ ๋น ๋ฅด๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๋•๊ธฐ ์œ„ํ•ฉ๋‹ˆ๋‹ค. -- [๊ณ ๊ธ‰ ์น˜ํŠธ์‹œํŠธ]() + - ๊ธฐ์ดˆ ์น˜ํŠธ์‹œํŠธ๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ TypeScript์— ๋Œ€ํ•ด ๋„ˆ๋ฌด ๋งŽ์€ ๊ณต๋ถ€๋ฅผ ํ•˜์ง€ ์•Š๊ณ ์„œ๋„ **์‹œ๊ฐ„ ํšจ์œจ์ **์œผ๋กœ React ๊ฐœ๋ฐœ์— TypeScript๋ฅผ ๋น ๋ฅด๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๋•๋Š” ๋ฐ ๊ทธ ๋ชฉ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. +- [๊ณ ๊ธ‰ ์น˜ํŠธ์‹œํŠธ]()๋Š” ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ type utilities/functions/render prop/higher order copmonents ๋˜๋Š” TS+React ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ž‘์„ฑํ•˜๊ณ ์ž ํ•˜๋Š” ๊ฐœ๋ฐœ์ž๋ฅผ ์œ„ํ•ด generic types์˜ ๊ณ ๊ธ‰ ์‚ฌ์šฉ๋ฒ•์— ๋Œ€ํ•œ ์ดํ•ด๋ฅผ ๋•์Šต๋‹ˆ๋‹ค. + - ์ „๋ฌธ์ ์ธ ๊ฐœ๋ฐœ์ž๋“ค์„ ์œ„ํ•œ ๋‹ค์–‘ํ•œ ํŒ๊ณผ ์š”๋ น๋“ค์„ ์†Œ๊ฐœํ•ฉ๋‹ˆ๋‹ค. + - DefinitelyTyped์— ๊ธฐ์—ฌํ•˜๊ธฐ ์œ„ํ•œ ์กฐ์–ธ์„ ๋“œ๋ฆฝ๋‹ˆ๋‹ค. + - ๊ณ ๊ธ‰ ์น˜ํŠธ์‹œํŠธ๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ TypeScript๋ฅผ ์ตœ๋Œ€ํ•œ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๋•๋Š” ๋ฐ ๊ทธ ๋ชฉ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. - [๋งˆ์ด๊ทธ๋ ˆ์ดํŒ… ์น˜ํŠธ์‹œํŠธ]() - [HOC ์น˜ํŠธ์‹œํŠธ]() From fc770f5e09727f9bab033eaa8a1aee781f8fbab6 Mon Sep 17 00:00:00 2001 From: Seong-Jin Kim Date: Wed, 24 Aug 2022 18:03:24 +0900 Subject: [PATCH 15/25] doc: translate Readme: migrating cheatsheet, hoc cheatsheet --- README.md | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index a5e9390..c558dae 100644 --- a/README.md +++ b/README.md @@ -27,15 +27,25 @@ TypeScript์— ์ž…๋ฌธํ•˜๋Š” React ๊ฐœ๋ฐœ์ž๋ฅผ ์œ„ํ•œ ์น˜ํŠธ์‹œํŠธ(Cheetsheets) # All React + TypeScript Cheatsheets -- [๊ธฐ์ดˆ ์น˜ํŠธ์‹œํŠธ]()๋Š” React ๊ฐœ๋ฐœ์ž๊ฐ€ React app์—์„œ TS ์‚ฌ์šฉ์„ ์‹œ์ž‘ํ•˜๋Š” ๊ฒƒ์— ๋„์›€์„ ์ฃผ๊ธฐ ์œ„ํ•œ ๋‚ด์šฉ์ด ์ฃผ๋ฅผ ์ด๋ฃน๋‹ˆ๋‹ค. +- [๊ธฐ์ดˆ ์น˜ํŠธ์‹œํŠธ(The Basic Cheatsheet)]()๋Š” React ๊ฐœ๋ฐœ์ž๊ฐ€ React app์—์„œ TS ์‚ฌ์šฉ์„ ์‹œ์ž‘ํ•˜๋Š” ๊ฒƒ์— ๋„์›€์„ ์ฃผ๊ธฐ ์œ„ํ•œ ๋‚ด์šฉ์ด ์ฃผ๋ฅผ ์ด๋ฃน๋‹ˆ๋‹ค. - ๋ชจ๋ฒ” ์‚ฌ๋ก€(Best Practices)๋ผ๊ณ  ์—ฌ๊ฒจ์ง€๋Š”, ๋ณต์‚ฌ + ๋ถ™์—ฌ๋„ฃ๊ธฐ ๊ฐ€๋Šฅํ•œ ์˜ˆ์‹œ - ๊ธฐ๋ณธ์ ์ธ TS Types ์‚ฌ์šฉ๋ฒ•๊ณผ ์„ค์ • ๋ฐฉ๋ฒ• - ์ž์ฃผ ๋ฌป๋Š” ์งˆ๋ฌธ(FAQ)์— ๋Œ€ํ•œ ๋‹ต๋ณ€ - Generic type logic์€ ๊นŠ์ด ๋‹ค๋ฃจ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ ๋Œ€์‹ , ์ดˆ์‹ฌ์ž๋“ค์„ ์œ„ํ•ด ๊ฐ„๋‹จํ•œ ํŠธ๋Ÿฌ๋ธ”์ŠˆํŒ… ๊ธฐ์ˆ ๋“ค์„ ์†Œ๊ฐœํ•ฉ๋‹ˆ๋‹ค. - ๊ธฐ์ดˆ ์น˜ํŠธ์‹œํŠธ๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ TypeScript์— ๋Œ€ํ•ด ๋„ˆ๋ฌด ๋งŽ์€ ๊ณต๋ถ€๋ฅผ ํ•˜์ง€ ์•Š๊ณ ์„œ๋„ **์‹œ๊ฐ„ ํšจ์œจ์ **์œผ๋กœ React ๊ฐœ๋ฐœ์— TypeScript๋ฅผ ๋น ๋ฅด๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๋•๋Š” ๋ฐ ๊ทธ ๋ชฉ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. -- [๊ณ ๊ธ‰ ์น˜ํŠธ์‹œํŠธ]()๋Š” ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ type utilities/functions/render prop/higher order copmonents ๋˜๋Š” TS+React ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ž‘์„ฑํ•˜๊ณ ์ž ํ•˜๋Š” ๊ฐœ๋ฐœ์ž๋ฅผ ์œ„ํ•ด generic types์˜ ๊ณ ๊ธ‰ ์‚ฌ์šฉ๋ฒ•์— ๋Œ€ํ•œ ์ดํ•ด๋ฅผ ๋•์Šต๋‹ˆ๋‹ค. +- [๊ณ ๊ธ‰ ์น˜ํŠธ์‹œํŠธ(The Advanced Cheatsheet)]()๋Š” ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ type utilities/functions/render prop/higher order copmonents ๋˜๋Š” TS+React ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ž‘์„ฑํ•˜๊ณ ์ž ํ•˜๋Š” ๊ฐœ๋ฐœ์ž๋ฅผ ์œ„ํ•ด generic types์˜ ๊ณ ๊ธ‰ ์‚ฌ์šฉ๋ฒ•์— ๋Œ€ํ•œ ์ดํ•ด๋ฅผ ๋•์Šต๋‹ˆ๋‹ค. - ์ „๋ฌธ์ ์ธ ๊ฐœ๋ฐœ์ž๋“ค์„ ์œ„ํ•œ ๋‹ค์–‘ํ•œ ํŒ๊ณผ ์š”๋ น๋“ค์„ ์†Œ๊ฐœํ•ฉ๋‹ˆ๋‹ค. - DefinitelyTyped์— ๊ธฐ์—ฌํ•˜๊ธฐ ์œ„ํ•œ ์กฐ์–ธ์„ ๋“œ๋ฆฝ๋‹ˆ๋‹ค. - ๊ณ ๊ธ‰ ์น˜ํŠธ์‹œํŠธ๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ TypeScript๋ฅผ ์ตœ๋Œ€ํ•œ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๋•๋Š” ๋ฐ ๊ทธ ๋ชฉ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. -- [๋งˆ์ด๊ทธ๋ ˆ์ดํŒ… ์น˜ํŠธ์‹œํŠธ]() -- [HOC ์น˜ํŠธ์‹œํŠธ]() +- [๋งˆ์ด๊ทธ๋ ˆ์ดํŒ… ์น˜ํŠธ์‹œํŠธ(The Migrating Cheatsheet)]()๋Š” ๋Œ€๊ทœ๋ชจ ์ฝ”๋“œ๋ฒ ์ด์Šค๋ฅผ JS ๋˜๋Š” Flow์—์„œ TypsScript๋กœ ์ ์ง„์ ์œผ๋กœ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ํ•˜๋Š” ๊ฒƒ์— ๋Œ€ํ•œ ๊ฒฝํ—˜์ž์˜ ์กฐ์–ธ์„ ์–ป๋Š”๋ฐ ๋„์›€์„ ์ค๋‹ˆ๋‹ค. + - ์šฐ๋ฆฌ๋Š” ์—ฌ๋Ÿฌ๋ถ„์ด ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์„ ํ•˜๋„๋ก ์„ค๋“ํ•˜๋ ค๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ฉฐ, ์ด๋ฏธ ๊ทธ๋ ‡๊ฒŒ ํ•˜๊ณ ์ž ๊ฒฐ์ •ํ•œ ์‚ฌ๋žŒ๋“ค์„ ๋•๊ณ ์ž ํ•ฉ๋‹ˆ๋‹ค. + - โš ๏ธ ์ด ์น˜ํŠธ์‹œํŠธ๋Š” ์ƒˆ๋กญ๊ฒŒ ๋งŒ๋“ค์–ด์ง„ ์น˜ํŠธ์‹œํŠธ ์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋„์›€์„ ์ฃผ๊ณ ์ž ํ•˜๋Š” ๋ชจ๋“  ๋ถ„๋“ค์„ ํ™˜์˜ํ•ฉ๋‹ˆ๋‹ค. +- [HOC ์น˜ํŠธ์‹œํŠธ(The HOC Cheatsheet)]()๋Š” ์˜ˆ์‹œ์™€ ํ•จ๊ป˜ HOC๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ๋ ค์ค๋‹ˆ๋‹ค. + - [Generics](https://www.typescriptlang.org/docs/handbook/2/generics.html)์— ๋Œ€ํ•œ ์ดํ•ด๊ฐ€ ์„ ํ–‰๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. + - โš ๏ธ ์ด ์น˜ํŠธ์‹œํŠธ๋Š” ์ƒˆ๋กญ๊ฒŒ ๋งŒ๋“ค์–ด์ง„ ์น˜ํŠธ์‹œํŠธ ์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋„์›€์„ ์ฃผ๊ณ ์ž ํ•˜๋Š” ๋ชจ๋“  ๋ถ„๋“ค์„ ํ™˜์˜ํ•ฉ๋‹ˆ๋‹ค. + +--- + +## ๊ธฐ์ดˆ ์น˜ํŠธ์‹œํŠธ (Basic Cheatsheet) + +### ๊ธฐ์ดˆ ์น˜ํŠธ์‹œํŠธ ๋ชฉ์ฐจ From 1dee798885a09dfc2da1063631290f5ca514fd9b Mon Sep 17 00:00:00 2001 From: Seong-Jin Kim Date: Fri, 26 Aug 2022 15:01:03 +0900 Subject: [PATCH 16/25] doc: section1 - setup typescript with react --- README.md | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/README.md b/README.md index c558dae..73b5e69 100644 --- a/README.md +++ b/README.md @@ -49,3 +49,83 @@ TypeScript์— ์ž…๋ฌธํ•˜๋Š” React ๊ฐœ๋ฐœ์ž๋ฅผ ์œ„ํ•œ ์น˜ํŠธ์‹œํŠธ(Cheetsheets) ## ๊ธฐ์ดˆ ์น˜ํŠธ์‹œํŠธ (Basic Cheatsheet) ### ๊ธฐ์ดˆ ์น˜ํŠธ์‹œํŠธ ๋ชฉ์ฐจ + +
+ +๋ชฉ์ฐจ ํ™•์žฅํ•˜๊ธฐ + +- [์„น์…˜ 1: React์— TypeScript ์„ค์ •ํ•˜๊ธฐ]() + + - [์ „์ œ์กฐ๊ฑด]() + +
+ + + +### ์„น์…˜ 1: React์— TypeScript ์„ค์ •ํ•˜๊ธฐ + +#### ์‹œ์ž‘ํ•˜๊ธฐ ์ „ ํ•„์š”ํ•œ ์‚ฌํ•ญ + +1. [React](https://reactjs.org)์— ๋Œ€ํ•œ ์ถฉ๋ถ„ํ•œ ์ดํ•ด +2. [TypeScript Types](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html) ([2ality's guide](http://2ality.com/2018/04/type-notation-typescript.html)๋ฅผ ์•Œ๊ณ ์žˆ์œผ๋ฉด ๋ฌธ์„œ๋ฅผ ์ดํ•ดํ•˜๋Š”๋ฐ ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ TypeScript๋ฅผ ์ฒ˜์Œ ์ ‘ํ•˜๋Š” ๋ถ„์ด๋ผ๋ฉด,[chibicodeโ€™s tutorial](https://ts.chibicode.com/todo/).)๋ฅผ ์ฐธ๊ณ ํ•ด ๋ณด์„ธ์š”. +3. [the TypeScript section in the official React docs](https://reactjs.org/docs/static-type-checking.html#typescript) ์ฝ๊ธฐ +4. [the React section of the new TypeScript playground](http://www.typescriptlang.org/play/index.html?jsx=2&esModuleInterop=true&e=181#example/typescript-with-react) ์ฝ๊ธฐ (์„ ํƒ์‚ฌํ•ญ: [the playground's](http://www.typescriptlang.org/play/index.html) Example Section์˜ 40+ examples ๋‹จ๊ณ„๋ฅผ ์ˆ˜ํ–‰ํ•ด ๋ณด๊ธฐ) + +์ด ๊ฐ€์ด๋“œ๋Š” ๋…์ž๊ฐ€ ๊ฐ€์žฅ ์ตœ์‹  ๋ฒ„์ „์˜ TypeScript์™€ React๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค. ์ด์ „ ๋ฒ„์ „์— ๋Œ€ํ•œ ์‚ฌํ•ญ์€ ํ™•์žฅ ๊ฐ€๋Šฅํ•œ `
` ํƒœ๊ทธ๋กœ ํ™•์ธ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. + +#### VS Code ํ™•์žฅ ํ”„๋กœ๊ทธ๋žจ(Extensions) + +- ๋ฆฌํŽ™ํ† ๋ง ๋ณด์กฐ https://marketplace.visualstudio.com/items?itemName=paulshen.paul-typescript-toolkit +- R+TS Code Snippets (์—ฌ๋Ÿฌ๊ฐ€์ง€ ํ™•์žฅ ํ”„๋กœ๊ทธ๋žจ์ด ์žˆ์Šต๋‹ˆ๋‹ค...) + - https://marketplace.visualstudio.com/items?itemName=infeng.vscode-react-typescript + - https://www.digitalocean.com/community/tutorials/the-best-react-extension-for-vs-code +- TypeScript ๊ณต์‹ ํ™•์žฅํ”„๋กœ๊ทธ๋žจ https://code.visualstudio.com/docs/languages/typescript + +#### React + TypeScript ์ž…๋ฌธ์ž ํ‚คํŠธ + +Cloud setups: + +- [TypeScript Playground with React](https://www.typescriptlang.org/play?#code/JYWwDg9gTgLgBAKjgQwM5wEoFNkGN4BmUEIcA5FDvmQNwCwAUKJLHAN5wCuqWAyjMhhYANFx4BRAgSz44AXzhES5Snhi1GjLAA8W8XBAB2qeAGEInQ0KjjtycABsscALxwAFAEpXAPnaM4OANjeABtA0sYUR4Yc0iAXVcxPgEhdwAGT3oGAOTJaXx3L19-BkDAgBMIXE4QLCsAOhhgGCckgAMATQsgh2BcAGssCrgAEjYIqwVmutR27MC5LM0yuEoYTihDD1zAgB4K4AA3H13yvbAfbs5e-qGRiYspuBmsVD2Aekuz-YAjThgMCMcCMpj6gxcbGKLj8MTiVnck3gAGo4ABGTxyU6rcrlMF3OB1H5wT7-QFGbG4z6HE65ZYMOSMIA)๋Š” ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜์ง€ ์•Š๊ณ  Types๋ฅผ ๋””๋ฒ„๊น…๋งŒ ํ•˜๋Š” ๊ฒฝ์šฐ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +- [CodeSandbox](http://ts.react.new) - cloud IDE, ๋งค์šฐ ๋น ๋ฅธ ๋ถ€ํŒ… ์†๋„๋ฅผ ๊ฐ€์ง‘๋‹ˆ๋‹ค. +- [Stackblitz](https://stackblitz.com/edit/react-typescript-base) - cloud IDE, ๋งค์šฐ ๋น ๋ฅธ ๋ถ€ํŒ… ์†๋„๋ฅผ ๊ฐ€์ง‘๋‹ˆ๋‹ค. + +Local dev setups: + +- [Next.js](https://nextjs.org/docs/basic-features/typescript): `npx create-next-app -e with-typescript` ๋ช…๋ น์–ด๋Š” ์ƒˆ๋กœ์šด NextJS ํ”„๋กœ์ ํŠธ๋ฅผ ํ˜„์žฌ ํด๋”์— ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. +- [Create React App](https://facebook.github.io/create-react-app/docs/adding-typescript): `npx create-react-app name-of-app --template typescript` ๋ช…๋ น์–ด๋Š” ์ƒˆ๋กœ์šด NextJS ํ”„๋กœ์ ํŠธ๋ฅผ ์ƒˆ๋กœ์šด ํด๋”์— ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. +- [Vite](https://vitejs.dev/): `npm create vite@latest my-react-ts-app -- --template react-ts` +- [Meteor](https://guide.meteor.com/build-tool.html#typescript): `meteor create --typescript name-of-my-new-typescript-app` +- [Ignite](https://github.com/infinitered/ignite#use-ignite-andross-infinite-red-andross-boilerplate) for React Native: `ignite new myapp` +- [TSDX](https://tsdx.io/): `npx tsdx create mylib` ๋ช…๋ น์–ด๋Š” React+TS _๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ_ ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. (in future: [TurboRepo](https://twitter.com/jaredpalmer/status/1346217789942591488)) + +
+๋‹ค๋ฅธ ๋„๊ตฌ๋“ค + +์•„์ง ๋ณด์™„์ด ํ•„์š”ํ•˜์ง€๋งŒ ํ™•์ธํ•ด ๋ณผ ๋งŒํ•œ ๊ฐ€์น˜๊ฐ€ ์žˆ๋Š” ๋„๊ตฌ๋“ค: + +- [Snowpack](): `npx create-snowpack-app my-app --template app-template-react-typescript` +- [Docusaurus v2](https://v2.docusaurus.io/docs/installation) with [TypeScript Support](https://v2.docusaurus.io/docs/typescript-support) +- [Parcel](https://v2.parceljs.org/languages/typescript/) +- [JP Morgan's `modular`](https://github.com/jpmorganchase/modular): CRA + TS + Yarn Workspaces toolkit. `yarn create modular-react-app ` + +Manual setup: + +- [Basarat's guide](https://github.com/basarat/typescript-react/tree/master/01%20bootstrap)๋Š” React + TypeScript + Webpack + Babel ์„ **์ˆ˜๋™์œผ๋กœ ์„ค์ •** ํ•  ๊ฒฝ์šฐ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +- ํŠนํžˆ, `@types/react`์™€ `@types/react-dom`๊ฐ€ ์„ค์น˜๋˜์–ด ์žˆ๋Š”์ง€ ํ™•์ธ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ([์ต์ˆ™ํ•˜์ง€ ์•Š์€ ๋‚ด์šฉ์ด๋ผ๋ฉด DefinitelyTyped project ์— ๋Œ€ํ•ด ๋” ์•Œ์•„๋ณด์„ธ์š”.](https://definitelytyped.org/)) +- ๋˜ํ•œ ๋งŽ์€ React + TypeScript bolierplates๋“ค์ด ์žˆ์Šต๋‹ˆ๋‹ค. [์šฐ๋ฆฌ์˜ ๋‹ค๋ฅธ ๋ฆฌ์†Œ์Šค ๋ฆฌ์ŠคํŠธ](https://react-typescript-cheatsheet.netlify.app/docs/basic/recommended/resources/)๋ฅผ ํ™•์ธํ•ด์ฃผ์„ธ์š”. + +
+ +#### ๋น„๋””์˜ค ํŠœํ† ๋ฆฌ์–ผ + +์•„๋ž˜์˜ 7๋ถ€๋กœ ๊ตฌ์„ฑ๋œ "React Typescript Course" ๋น„๋””์˜ค ์‹œ๋ฆฌ์ฆˆ๋ฅผ ํ†ตํ•ด TypeScript with React์— ๋Œ€ํ•œ ์†Œ๊ฐœ๋ฅผ ๋“ค์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + + + react typescript course video series + + + From 1b6bbf8f248a7d47972d8d763134cf002a212594 Mon Sep 17 00:00:00 2001 From: Seong-Jin Kim Date: Fri, 26 Aug 2022 19:20:19 +0900 Subject: [PATCH 17/25] doc: 2. getting started - functional components - why is `React.FC` idscouraged? --- README.md | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/README.md b/README.md index 73b5e69..8b04b41 100644 --- a/README.md +++ b/README.md @@ -129,3 +129,60 @@ Manual setup: + +### Section 2: ์‹œ์ž‘ํ•˜๊ธฐ + + + +#### ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ + +ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ๋Š” `props`๋ฅผ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋ฐ›๊ณ  JSX element๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ์ผ๋ฐ˜์ ์ธ ํ•จ์ˆ˜๋กœ ์ž‘์„ฑ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +```tsx +// props์˜ ํƒ€์ž… ์ •์˜ - ๋” ๋งŽ์€ ์˜ˆ์‹œ๋Š” "์ปดํฌ๋„ŒํŠธ Props ํƒ€์ดํ•‘"์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +type AppProps = { + message: string; +}; /* export ํ•œ๋‹ค๋ฉด consumer๊ฐ€ extendํ•  ์ˆ˜ ์žˆ๋„๋ก `interface`๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”. */ + +// ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ€์žฅ ์‰ฌ์šด ๋ฐฉ๋ฒ•; return type์€ ์ถ”๋ก ๋ฉ๋‹ˆ๋‹ค. +const App = ({ message }: AppProps) =>
{message}
; + +// ์‹ค์ˆ˜๋กœ ๋‹ค๋ฅธ ํƒ€์ž…์„ ๋ฐ˜ํ™˜ํ•˜์˜€์„ ๋•Œ ์—๋Ÿฌ๊ฐ€ raise ๋˜๋„๋ก return type์„ ๋ช…์‹œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +const App = ({ message }: AppProps): JSX.Element =>
{message}
; + +// type ์„ ์–ธ์„ ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ ์„ ์–ธ์— ํฌํ•จ์‹œํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.;์ด ๋ฐฉ๋ฒ•์€ prop types์— ์ด๋ฆ„์„ ๋ถ™์ด์ง€ ์•Š์•„๋„ ๋˜์ง€๋งŒ ์ฝ”๋“œ๊ฐ€ ๋ฐ˜๋ณต๋ฉ๋‹ˆ๋‹ค. +const App = ({ message }: { message: string }) =>
{message}
; +``` + +> Tip: type destructure ์„ ์–ธ์„ ์œ„ํ•ด [Paul Shen's VS Code Extension](https://marketplace.visualstudio.com/items?itemName=paulshen.paul-typescript-toolkit)๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ([keyboard shortcut](https://twitter.com/_paulshen/status/1392915279466745857?s=20)์„ ์ถ”๊ฐ€ ํ•˜์„ธ์š”.) + +
+ +React.FC๊ฐ€ ๊ถŒ์žฅ๋˜์ง€ ์•Š๋Š” ์ด์œ ๋Š” ๋ฌด์—‡์ผ๊นŒ์š”? React.FunctionComponent/React.VoidFunctionComponent๋Š” ์–ด๋–ค๊ฐ€์š”? + +React+TypeScript codebases์—์„œ ๋‹ค์Œ ๋ณด์•˜์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +```tsx +const App: React.FunctionComponent<{ message: string }> = ({ message }) =>
{message}
; +``` + +ํ•˜์ง€๋งŒ, ํ˜„์žฌ `React.FunctionComponent` (๋˜๋Š” ๊ฐ„๋žตํ•˜๊ฒŒ ์จ์„œ `React.FC`)๋Š” [๊ถŒ์žฅ๋˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ](https://github.com/facebook/create-react-app/pull/8177)์— ๋Œ€๋ถ€๋ถ„์˜ ์‚ฌ๋žŒ๋“ค์ด ๋™์˜ํ•ฉ๋‹ˆ๋‹ค. ๋ฌผ๋ก  ์ด ์ฃผ์ œ์— ๋Œ€ํ•œ ๋ฏธ๋ฌ˜ํ•œ ์˜๊ฒฌ ์ฐจ์ด๊ฐ€ ์žˆ์„ ์ˆ˜๋Š” ์žˆ์ง€๋งŒ, ๋งŒ์•ฝ ์ด ์˜๊ฒฌ์— ๋™์˜ํ•˜๊ณ  `React.FC`๋ฅผ ๋‹น์‹ ์˜ ์ฝ”๋“œ๋ฒ ์ด์Šค์—์„œ ์ œ๊ฑฐํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด, [์ด jscodeshift codemond](https://github.com/gndelia/codemod-replace-react-fc-typescript)๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +"์ผ๋ฐ˜์ ์ธ ํ•จ์ˆ˜" ๋ฒ„์ „๊ณผ์˜ ์ฐจ์ด์ ๋“ค์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. + +- `React.FunctionComponent`๋Š” return type์„ ๋ช…์‹œ์ ์œผ๋กœ ๋ฐํž™๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ผ๋ฐ˜์ ์ธ ํ•จ์ˆ˜ ๋ฒ„์ „์€ ์•”์‹œ์ ์ž…๋‹ˆ๋‹ค(๋˜๋Š” ์ถ”๊ฐ€์ ์ธ ์–ด๋…ธํ…Œ์ด์…˜(annotation)์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค). + +- `React.FunctionComponent` is explicit about the return type, while the normal function version is implicit (or else needs additional annotation). + +- `displayName`, `propTypes`, ๊ทธ๋ฆฌ๊ณ  `defaultProps`์™€ ๊ฐ™์€ static properties๋ฅผ ์œ„ํ•œ ์ž๋™์™„์„ฑ(autocomplete)๊ณผ ํƒ€์ž… ์ฒดํฌ(Typechecking)๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. + + - `React.FunctionComponent`์™€ ํ•จ๊ป˜ `defaultProps`์„ ์‚ฌ์šฉํ•˜๋Š”๋ฐ ๋ช‡ ๊ฐ€์ง€ ์•Œ๋ ค์ง„ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. [๋ฌธ์ œ์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ](https://github.com/typescript-cheatsheets/react/issues/87)์„ ํ™•์ธํ•˜์„ธ์š”. ์šฐ๋ฆฌ๋Š” ๊ฐœ๋ฐœ์ž๋‹˜์ด ์ฐพ์•„๋ณผ ์ˆ˜ ์žˆ๋Š” ๋ณ„๊ฐœ์˜ `defaultProps` ์„น์…˜์„ ์ œ๊ณตํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. + +- [React 18 type ์—…๋ฐ์ดํŠธ](https://github.com/DefinitelyTyped/DefinitelyTyped/pull/56210) ์ด์ „์—๋Š”, `React.FunctionComponent`์ด `children`์— ๋Œ€ํ•œ ์•”์‹œ์ ์ธ ์ •์˜(implicit definition)๋ฅผ ์ œ๊ณตํ–ˆ์—ˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์—ด๋ค ํ† ๋ก  ๊ณผ์ •์„ ๊ฑฐ์ณค๊ณ  ๊ฒฐ๊ณผ์ ์œผ๋กœ [`React.FC`๊ฐ€ Create React App TypeScript template์—์„œ ์ œ๊ฑฐ](https://github.com/facebook/create-react-app/pull/8177)๋œ ์ด์œ  ์ค‘ ํ•˜๋‚˜๊ฐ€ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. + +```tsx +// React 18 types ์ด์ „ +const Title: React.FunctionComponent<{ title: string }> = ({ children, title }) => ( +
{children}
+); +``` From 0f7909abb821fa1b2757fe1c20816a2e65da2159 Mon Sep 17 00:00:00 2001 From: Seong-Jin Kim Date: Fri, 26 Aug 2022 19:25:28 +0900 Subject: [PATCH 18/25] fix: Prerequisites --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8b04b41..564ecbd 100644 --- a/README.md +++ b/README.md @@ -67,7 +67,7 @@ TypeScript์— ์ž…๋ฌธํ•˜๋Š” React ๊ฐœ๋ฐœ์ž๋ฅผ ์œ„ํ•œ ์น˜ํŠธ์‹œํŠธ(Cheetsheets) #### ์‹œ์ž‘ํ•˜๊ธฐ ์ „ ํ•„์š”ํ•œ ์‚ฌํ•ญ 1. [React](https://reactjs.org)์— ๋Œ€ํ•œ ์ถฉ๋ถ„ํ•œ ์ดํ•ด -2. [TypeScript Types](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html) ([2ality's guide](http://2ality.com/2018/04/type-notation-typescript.html)๋ฅผ ์•Œ๊ณ ์žˆ์œผ๋ฉด ๋ฌธ์„œ๋ฅผ ์ดํ•ดํ•˜๋Š”๋ฐ ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ TypeScript๋ฅผ ์ฒ˜์Œ ์ ‘ํ•˜๋Š” ๋ถ„์ด๋ผ๋ฉด,[chibicodeโ€™s tutorial](https://ts.chibicode.com/todo/).)๋ฅผ ์ฐธ๊ณ ํ•ด ๋ณด์„ธ์š”. +2. [TypeScript Types](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html)์ฃผ์ œ์— ๋Œ€ํ•œ ์ดํ•ด ([2ality's guide](http://2ality.com/2018/04/type-notation-typescript.html)๋ฅผ ์•Œ๊ณ ์žˆ์œผ๋ฉด ๋ฌธ์„œ๋ฅผ ์ดํ•ดํ•˜๋Š”๋ฐ ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ TypeScript๋ฅผ ์ฒ˜์Œ ์ ‘ํ•˜๋Š” ๋ถ„์ด๋ผ๋ฉด,[chibicodeโ€™s tutorial](https://ts.chibicode.com/todo/)๋ฅผ ์ฐธ๊ณ ํ•ด ๋ณด์„ธ์š”.) 3. [the TypeScript section in the official React docs](https://reactjs.org/docs/static-type-checking.html#typescript) ์ฝ๊ธฐ 4. [the React section of the new TypeScript playground](http://www.typescriptlang.org/play/index.html?jsx=2&esModuleInterop=true&e=181#example/typescript-with-react) ์ฝ๊ธฐ (์„ ํƒ์‚ฌํ•ญ: [the playground's](http://www.typescriptlang.org/play/index.html) Example Section์˜ 40+ examples ๋‹จ๊ณ„๋ฅผ ์ˆ˜ํ–‰ํ•ด ๋ณด๊ธฐ) From fb14896be0fe14306f28e2ab49a857977be8b211 Mon Sep 17 00:00:00 2001 From: Seong-Jin Kim Date: Fri, 26 Aug 2022 19:27:45 +0900 Subject: [PATCH 19/25] fix: why is React.FC discouraged? --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index 564ecbd..8953eaf 100644 --- a/README.md +++ b/README.md @@ -172,8 +172,6 @@ const App: React.FunctionComponent<{ message: string }> = ({ message }) =>
- `React.FunctionComponent`๋Š” return type์„ ๋ช…์‹œ์ ์œผ๋กœ ๋ฐํž™๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ผ๋ฐ˜์ ์ธ ํ•จ์ˆ˜ ๋ฒ„์ „์€ ์•”์‹œ์ ์ž…๋‹ˆ๋‹ค(๋˜๋Š” ์ถ”๊ฐ€์ ์ธ ์–ด๋…ธํ…Œ์ด์…˜(annotation)์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค). -- `React.FunctionComponent` is explicit about the return type, while the normal function version is implicit (or else needs additional annotation). - - `displayName`, `propTypes`, ๊ทธ๋ฆฌ๊ณ  `defaultProps`์™€ ๊ฐ™์€ static properties๋ฅผ ์œ„ํ•œ ์ž๋™์™„์„ฑ(autocomplete)๊ณผ ํƒ€์ž… ์ฒดํฌ(Typechecking)๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. - `React.FunctionComponent`์™€ ํ•จ๊ป˜ `defaultProps`์„ ์‚ฌ์šฉํ•˜๋Š”๋ฐ ๋ช‡ ๊ฐ€์ง€ ์•Œ๋ ค์ง„ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. [๋ฌธ์ œ์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ](https://github.com/typescript-cheatsheets/react/issues/87)์„ ํ™•์ธํ•˜์„ธ์š”. ์šฐ๋ฆฌ๋Š” ๊ฐœ๋ฐœ์ž๋‹˜์ด ์ฐพ์•„๋ณผ ์ˆ˜ ์žˆ๋Š” ๋ณ„๊ฐœ์˜ `defaultProps` ์„น์…˜์„ ์ œ๊ณตํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. From ca36336b216e8fb52d538196f5756b29ec66fbe7 Mon Sep 17 00:00:00 2001 From: Seong-Jin Kim Date: Tue, 30 Aug 2022 01:33:43 +0900 Subject: [PATCH 20/25] doc: translate section-function component --- README.md | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/README.md b/README.md index 8953eaf..b9cb336 100644 --- a/README.md +++ b/README.md @@ -184,3 +184,75 @@ const Title: React.FunctionComponent<{ title: string }> = ({ children, title })
{children}
); ``` + +
+(Deprecated)React.VoidFunctionComponent ๋˜๋Š” React.VFC ์‚ฌ์šฉํ•˜๊ธฐ + +[@types/react 16.9.48](https://github.com/DefinitelyTyped/DefinitelyTyped/pull/46643)์—์„œ, `React.VoidFunctionComponent` ๋˜๋Š” `React.VFC` type์€ `children`์„ ๋ช…์‹œ์ ์œผ๋กœ ํƒ€์ดํ•‘(typing) ํ•˜๊ธฐ ์œ„ํ•ด ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค. +ํ•˜์ง€๋งŒ, `React.VFC`์™€ `React.VoidFunctionComponent`๋Š” React 18 (https://github.com/DefinitelyTyped/DefinitelyTyped/pull/59882)์—์„œ ๋”์ด์ƒ ์‚ฌ์šฉ๋˜์ง€ ์•Š๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค(deprecated). ๋”ฐ๋ผ์„œ ์ด ์ž„์‹œ๋ฐฉํŽธ์€ React 18+ ์—์„œ ๋”์ด์ƒ ๊ถŒ์žฅ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. + +์ผ๋ฐ˜์ ์ธ ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ๋‚˜ `React.FC`๋ฅผ ์‚ฌ์šฉํ•ด ์ฃผ์„ธ์š”. + +```ts +type Props = { foo: string }; + +// ์ง€๊ธˆ์€ ๊ดœ์ฐฎ์ง€๋งŒ, ๋ฏธ๋ž˜์—๋Š” ์—๋Ÿฌ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ฌ ๊ฒƒ์ž…๋‹ˆ๋‹ค. +const FunctionComponent: React.FunctionComponent = ({ foo, children }: Props) => { + return ( +
+ {foo} {children} +
+ ); // OK +}; + +// ์ง€๊ธˆ์€ ์—๋Ÿฌ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๊ณ , ๋ฏธ๋ž˜์—๋Š” ๋”์ด์ƒ ์‚ฌ์šฉ๋˜์ง€ ์•Š์„๊ฒƒ์ž…๋‹ˆ๋‹ค.(Deprecated) +const VoidFunctionComponent: React.VoidFunctionComponent = ({ foo, children }) => { + return ( +
+ {foo} + {children} +
+ ); +}; +``` + +
+ +- _๋ฏธ๋ž˜์—๋Š”_, props๋ฅผ ์ž๋™์œผ๋กœ `readonly` ๋ผ๊ณ  ํ‘œ์‹œํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ, props ๊ฐ์ฒด๊ฐ€ ํŒŒ๋ผ๋ฏธํ„ฐ ๋ฆฌ์ŠคํŠธ์—์„œ destructure ๋œ๋‹ค๋ฉด, ์ด๊ฒƒ์€ ์˜๋ฏธ์—†๋Š” ํ–‰๋™ ์ž…๋‹ˆ๋‹ค. + +๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ์—๋Š” ์–ด๋–ค syntax๋ฅผ ์‚ฌ์šฉํ•˜๋˜์ง€ ํฐ ์ฐจ์ด๊ฐ€ ์—†์ง€๋งŒ, `React.FunctionComponent`์˜ ๋ณด๋‹ค ๋ช…์‹œ์ ์ธ ํŠน์„ฑ์„ ์„ ํ˜ธํ•˜๋Š” ๊ฒƒ์ด ์ข‹์„๊ฒƒ์ž…๋‹ˆ๋‹ค. + +
+ +
+์ฃผ์˜ํ•ด์•ผ ํ•  ์‚ฌํ•ญ + +๋‹ค์Œ์˜ ํŒจํ„ด์€ ์ง€์›๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. : + +**์กฐ๊ฑด๋ถ€ ๋ Œ๋”๋ง(conditional rendering)** + +```tsx +const MyConditionalComponent = ({ shouldRender = false }) => (shouldRender ?
: false); // JS ์—์„œ๋„ ์ด๋ ‡๊ฒŒ ํ•˜์ง€ ๋งˆ์‹ญ์‹œ์˜ค. +const el = ; // ์—๋Ÿฌ๋ฅผ throw ํ•ฉ๋‹ˆ๋‹ค. +``` + +์ด ํŒจํ„ด์ด ์ง€์›๋˜์ง€ ์•Š๋Š” ์ด์œ ๋Š” ์ปดํŒŒ์ผ๋Ÿฌ์˜ ํ•œ๊ณ„ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ๋Š” JSX expression ๋˜๋Š” `null` ์ด์™ธ์˜ ๋‹ค๋ฅธ ์–ด๋–ค ๊ฒƒ๋„ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์—†๋Š” ๊ฒƒ์ด ๋ฐ˜ํ™˜๋œ๋‹ค๋ฉด ํ•ด๋‹น ํƒ€์ž…์€ `Element`์— ํ• ๋‹น๋  ์ˆ˜ ์—†๋‹ค๋Š” ์—๋Ÿฌ ๋ฉ”์„ธ์ง€๋ฅผ ๋ณด๊ฒŒ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ("{the other type} is not assignable to `Element`.") + +**Array.fill** + +```tsx +const MyArrayComponent = () => Array(5).fill(
); +const el2 = ; // throws an error +``` + +์•„์‰ฝ๊ฒŒ๋„ ํ•จ์ˆ˜์˜ ํƒ€์ž…์„ annotate ํ•˜๋Š” ๊ฒƒ์€ ์•„๋ฌด๋Ÿฐ ๋„์›€์ด ๋˜์ง€ ์•Š์„๊ฒƒ์ž…๋‹ˆ๋‹ค. React๊ฐ€ ์ง€์›ํ•˜๋Š” ๋‹ค๋ฅธ ํŠน๋ณ„ํ•œ ํƒ€์ž…(exotic type)์„ ๋ฐ˜ํ™˜ํ•˜๊ณ ์ž ํ•œ๋‹ค๋ฉด ํƒ€์ž… ํ‘œ๋ช…(type assertion)์„ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. : + +```tsx +const MyArrayComponent = () => Array(5).fill(
) as any as JSX.Element; +``` + +[์—ฌ๊ธฐ์„œ @ferdaber ์˜ ์„ค๋ช…์„ ํ™•์ธํ•ด๋ณด์„ธ์š”](https://github.com/typescript-cheatsheets/react/issues/57). + +
+ + From e9e97d19b213de6098feaa76acbc567db9bcc196 Mon Sep 17 00:00:00 2001 From: Seong-Jin Kim Date: Tue, 30 Aug 2022 01:39:36 +0900 Subject: [PATCH 21/25] fix: typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b9cb336..287524f 100644 --- a/README.md +++ b/README.md @@ -189,7 +189,7 @@ const Title: React.FunctionComponent<{ title: string }> = ({ children, title }) (Deprecated)React.VoidFunctionComponent ๋˜๋Š” React.VFC ์‚ฌ์šฉํ•˜๊ธฐ [@types/react 16.9.48](https://github.com/DefinitelyTyped/DefinitelyTyped/pull/46643)์—์„œ, `React.VoidFunctionComponent` ๋˜๋Š” `React.VFC` type์€ `children`์„ ๋ช…์‹œ์ ์œผ๋กœ ํƒ€์ดํ•‘(typing) ํ•˜๊ธฐ ์œ„ํ•ด ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค. -ํ•˜์ง€๋งŒ, `React.VFC`์™€ `React.VoidFunctionComponent`๋Š” React 18 (https://github.com/DefinitelyTyped/DefinitelyTyped/pull/59882)์—์„œ ๋”์ด์ƒ ์‚ฌ์šฉ๋˜์ง€ ์•Š๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค(deprecated). ๋”ฐ๋ผ์„œ ์ด ์ž„์‹œ๋ฐฉํŽธ์€ React 18+ ์—์„œ ๋”์ด์ƒ ๊ถŒ์žฅ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. +ํ•˜์ง€๋งŒ, `React.VFC`์™€ `React.VoidFunctionComponent`๋Š” React 18 (https://github.com/DefinitelyTyped/DefinitelyTyped/pull/59882) ์—์„œ ๋”์ด์ƒ ์‚ฌ์šฉ๋˜์ง€ ์•Š๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค(deprecated). ๋”ฐ๋ผ์„œ ์ด ์ž„์‹œ๋ฐฉํŽธ์€ React 18+ ์—์„œ ๋”์ด์ƒ ๊ถŒ์žฅ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์ธ ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ๋‚˜ `React.FC`๋ฅผ ์‚ฌ์šฉํ•ด ์ฃผ์„ธ์š”. From 08089246b6ce389d150d1ec9f3733010ffca7764 Mon Sep 17 00:00:00 2001 From: Seong-Jin Kim Date: Sun, 4 Sep 2022 05:07:06 +0900 Subject: [PATCH 22/25] =?UTF-8?q?doc:=20useState,=20useReducer=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) diff --git a/README.md b/README.md index 287524f..d3b7a69 100644 --- a/README.md +++ b/README.md @@ -256,3 +256,93 @@ const MyArrayComponent = () => Array(5).fill(
) as any as JSX.Element;
+ + + +#### Hooks + +Hook์€ [`@types/react` v16.8 ์ด์ƒ๋ถ€ํ„ฐ ์ง€์›๋ฉ๋‹ˆ๋‹ค](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/a05cc538a42243c632f054e42eab483ebf1560ab/types/react/index.d.ts#L800-L1031). + +#### useState + +ํƒ€์ž… ์ถ”๋ก (Type inference)์€ ๊ฐ„๋‹จํ•œ ๊ฐ’๋“ค์— ์ž˜ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค: + +```tsx +const [state, setState] = useState(false); +// `state` ๋Š” boolean ์œผ๋กœ ์ถ”๋ก ๋ฉ๋‹ˆ๋‹ค. +// `setState` ๋Š” boolean ๊ฐ’ ๋งŒ์„ ๋ฐ›์Šต๋‹ˆ๋‹ค. +``` + +ํƒ€์ž… ์ถ”๋ก ์— ๋ณต์žกํ•œ ํƒ€์ž…์„ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค๋ฉด [์ถ”๋ก ๋œ ํƒ€์ž…(Inferred Types) ์‚ฌ์šฉํ•˜๊ธฐ](https://react-typescript-cheatsheet.netlify.app/docs/basic/troubleshooting/types/#using-inferred-types) ๋„ ํ™•์ธํ•ด๋ณด์„ธ์š”. + +ํ•˜์ง€๋งŒ ๋งŽ์€ hook ๋“ค์€ null ๊ฐ™์€ ๊ฐ’๋ฅผ ๋””ํดํŠธ ๊ฐ’์œผ๋กœ ์ดˆ๊ธฐํ™” ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์–ด๋–ป๊ฒŒ ํƒ€์ž…์„ ์ง€์ •ํ•˜๋Š”์ง€ ๊ถ๊ธˆํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ช…์‹œ์ ์œผ๋กœ ํƒ€์ž…์„ ์„ ์–ธํ•˜๊ณ , union type์„ ์‚ฌ์šฉํ•˜์„ธ์š”.: + +```tsx +const [user, setUser] = useState(null); + +// later... +setUser(newUser); +``` + +๋งŒ์•ฝ useState์„ค์ • ์งํ›„์— state๊ฐ€ ์ดˆ๊ธฐํ™”๋˜๊ณ  ๊ทธ ์ดํ›„์— ํ•ญ์ƒ ๊ฐ’์„ ๊ฐ€์ง„๋‹ค๋ฉด, ํƒ€์ž… ํ‘œ๋ช…(type assertions)์„ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. + +```tsx +const [user, setUser] = useState({} as User); + +// later... +setUser(newUser); +``` + +์ด ๋ฐฉ๋ฒ•์€ ์ผ์‹œ์ ์œผ๋กœ ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ ์ปดํŒŒ์ผ๋Ÿฌ์—๊ฒŒ `{}`๊ฐ€ `User`์˜ type์ด๋ผ๊ณ  "๊ฑฐ์ง“๋ง" ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ ํ›„์— `user` state๋ฅผ ์„ค์ •ํ•˜์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ๋‚˜๋จธ์ง€ ์ฝ”๋“œ๊ฐ€ `user`๋Š” `User` ํƒ€์ž…์ด๋ผ๋Š” ์‚ฌ์‹ค์— ์˜์กด๊ณ  ์ด๊ฒƒ์€ ๋Ÿฐํƒ€์ž… ์—๋Ÿฌ๋กœ ์ด์–ด์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +#### useReducer + +Reducer actions๋ฅผ ์œ„ํ•ด [Discriminated Unions](https://www.typescriptlang.org/docs/handbook/typescript-in-5-minutes-func.html#discriminated-unions)๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. reducer์˜ return type์„ ์ •์˜ํ•˜๋Š” ๊ฒƒ์„ ์žŠ์ง€ ๋งˆ์„ธ์š”. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ๊ฐ€ return type์„ ์ถ”๋ก ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. + +```tsx +import { useReducer } from "react"; + +const initialState = { count: 0 }; + +type ACTIONTYPE = { type: "increment"; payload: number } | { type: "decrement"; payload: string }; + +function reducer(state: typeof initialState, action: ACTIONTYPE) { + switch (action.type) { + case "increment": + return { count: state.count + action.payload }; + case "decrement": + return { count: state.count - Number(action.payload) }; + default: + throw new Error(); + } +} + +function Counter() { + const [state, dispatch] = useReducer(reducer, initialState); + return ( + <> + Count: {state.count} + + + + ); +} +``` + +[TypeScript Playground์—์„œ ๋ณด๊ธฐ](https://www.typescriptlang.org/play?#code/LAKFEsFsAcHsCcAuACAVMghgZ2QJQKYYDGKAZvLJMgOTyEnUDcooRsAdliuO+IuBgA2AZUQZE+ZAF5kAbzYBXdogBcyAAwBfZmBCIAntEkBBAMIAVAJIB5AHLmAmgAUAotOShkyAD5zkBozVqHiI6SHxlagAaZGgMfUFYDAATNXYFSAAjfHhNDxAvX1l-Q3wg5PxQ-HDImLiEpNTkLngeAHM8ll1SJRJwDmQ6ZIUiHIAKLnEykqNYUmQePgERMQkY4n4ONTMrO0dXAEo5T2aAdz4iAAtkMY3+9gA6APwj2ROvImxJYPYqmsRqCp3l5BvhEAp4Ow5IplGpJhIHjCUABqTB9DgPeqJFLaYGfLDfCp-CIAoEFEFeOjgyHQ2BKVTNVb4RF05TIAC0yFsGWy8Fu6MeWMaB1x5K8FVIGAUglUwK8iEuFFOyHY+GVLngFD5Bx0Xk0oH13V6myhplZEm1x3JbE4KAA2vD8DFkuAsHFEFcALruAgbB4KAkEYajPlDEY5GKLfhCURTHUnKkQqFjYEAHgAfHLkGb6WpZI6WfTDRSvKnMgpEIgBhxTIJwEQANZSWRjI5SdPIF1u8RXMayZ7lSphEnRWLxbFNagAVmomhF6fZqYA9OXKxxM2KQWWK1WoTW643m63pB2u+7e-3SkEQsPamOGik1FO55p08jl6vdxuKcvv8h4yAmhAA) + +
+ +Redux์—์„œ Reducer์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๊ธฐ + +Reducer funciton์„ ์ž‘์„ฑํ•˜๊ธฐ ์œ„ํ•ด [redux](https://github.com/reduxjs/redux)๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ, return type์„ ์ฒ˜๋ฆฌํ•˜๋Š” `Reducer` ํ˜•์‹์˜ ํŽธ๋ฆฌํ•œ helper๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +์œ„์˜ reducer example์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ฐ”๋€” ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. : + +```tsx +import { Reducer } from 'redux'; + +export function reducer: Reducer() {} +``` + +
From ec40c694b244d756118257feb81c332d809c538d Mon Sep 17 00:00:00 2001 From: Seong-Jin Kim Date: Thu, 8 Sep 2022 01:57:38 +0900 Subject: [PATCH 23/25] doc: translate useEffect / useLayoutEffect --- README.md | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/README.md b/README.md index d3b7a69..c9a1349 100644 --- a/README.md +++ b/README.md @@ -346,3 +346,43 @@ export function reducer: Reducer() {} ``` + +#### useEffect / useLayoutEffect + +`userEffect`์™€ `userLayoutEffect` ๋‘˜ ๋‹ค side effect๋ฅผ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋˜๊ณ  ์„ ํƒ์ ์œผ๋กœ cleanup function์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋งŒ์•ฝ ์ด hook๋“ค์ด ๋ฐ˜ํ™˜ ๊ฐ’์„ ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด, type์ด ํ•„์š” ์—†๋‹ค๋Š” ๋œป์ž…๋‹ˆ๋‹ค. `useEffect`๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ, ํ•จ์ˆ˜ ๋˜๋Š” `undefined` ์ด์™ธ์˜ ๋‹ค๋ฅธ ๊ฒƒ์„ ๋ฐ˜ํ™˜ํ•˜์ง€ ์•Š๋„๋ก ์ฃผ์˜ํ•˜์„ธ์š”. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด TypeScript์™€ React๋Š” ๋‹น์‹ ์—๊ฒŒ ๋น„๋ช…์„ ์ง€๋ฅผ๊ฒƒ์ž…๋‹ˆ๋‹ค. Arros functions๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ์ด ๋ฌธ์ œ๋Š” ๋‹ค์†Œ ํŒŒ์•…ํ•˜๊ธฐ ์–ด๋ ค์šธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. : + +```ts +function DelayedEffect(props: { timerMs: number }) { + const { timerMs } = props; + + useEffect( + () => + setTimeout(() => { + /* do stuff */ + }, timerMs), + [timerMs] + ); + // ๋‚˜์œ ์˜ˆ์‹œ! setTimeout์€ ์•”๋ฌต์ ์œผ๋กœ ์ˆซ์ž๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. + // arrow function์˜ body๊ฐ€ ์ค‘๊ด„ํ˜ธ๋กœ ๊ฐ์‹ธ์ง€์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. + return null; +} +``` + +
+์œ„ ์˜ˆ์‹œ์— ๋Œ€ํ•œ ํ•ด๊ฒฐ์ฑ… + +```tsx +function DelayedEffect(props: { timerMs: number }) { + const { timerMs } = props; + + useEffect(() => { + setTimeout(() => { + /* do stuff */ + }, timerMs); + }, [timerMs]); + // ๋” ๋‚˜์€ ๋ฐฉ๋ฒ•; ํ™•์‹คํ•˜๊ฒŒ undefined๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ธฐ ์œ„ํ•ด์„œ void keyword๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”. + return null; +} +``` + +
From 671fdffb3cce709fb4549c0d8c54efdd749fe6c1 Mon Sep 17 00:00:00 2001 From: Seong-Jin Kim Date: Thu, 8 Sep 2022 02:22:21 +0900 Subject: [PATCH 24/25] doc: translate useRef --- README.md | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/README.md b/README.md index c9a1349..7b3e607 100644 --- a/README.md +++ b/README.md @@ -386,3 +386,77 @@ function DelayedEffect(props: { timerMs: number }) { ``` + +#### useRef + +TypeScript์—์„œ `useRef`๋Š” type argument๊ฐ€ ์ดˆ๊ธฐ ๊ฐ’์„ ์™„์ „ํžˆ ํฌํ•จ(cover)ํ•˜๋Š”์ง€ ์•„๋‹Œ์ง€์— ๋”ฐ๋ผ[read-only](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/abd69803c1b710db58d511f4544ec1b70bc9077c/types/react/v16/index.d.ts#L1025-L1039)๋˜๋Š” [mutable](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/abd69803c1b710db58d511f4544ec1b70bc9077c/types/react/v16/index.d.ts#L1012-L1023) ๋‘˜ ์ค‘ ํ•˜๋‚˜๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๊ฐ์ž์˜ use case์— ๋งž๋Š” ๊ฒƒ์„ ์„ ํƒํ•˜์„ธ์š”. + +##### Option 1: DOM element ref + +**[DOM element์— ์ ‘๊ทผํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š”](https://reactjs.org/docs/refs-and-the-dom.html):** element type ๋งŒ์„ argument๋กœ ๋„˜๊ฒจ์ฃผ๊ณ  `null`์„ ์ดˆ๊ธฐ ๊ฐ’์œผ๋กœ ์‚ฌ์šฉํ•˜์„ธ์š”. ์ด ๊ฒฝ์šฐ์—, ๋ฐ˜ํ™˜๋˜๋Š” reference๋Š” React์— ์˜ํ•ด ๊ด€๋ฆฌ๋˜๋Š” read-only `.current`๋ฅผ ๊ฐ€์งˆ ๊ฒƒ์ž…๋‹ˆ๋‹ค. TypeScript๋Š” ์ด ref๋ฅผ element์˜ `ref` prop์œผ๋กœ ์ „๋‹ฌ ๋ฐ›๊ธฐ๋ฅผ ๊ธฐ๋Œ€ํ•ฉ๋‹ˆ๋‹ค. : + +```tsx +function Foo() { + // - ๊ฐ€๋Šฅํ•œ ์ƒ์„ธํ•˜๊ฒŒ ์ž‘์„ฑํ•˜์„ธ์š”. ์˜ˆ๋ฅผ๋“ค๋ฉด, HTMLDivElement๋Š” HTMLElement๋ณด๋‹ค ๋” ์ข‹๊ณ , + // Element๋ณด๋‹ค๋Š” ํ›จ์‹  ๋” ์ข‹์€ ์„ ํƒ์ž…๋‹ˆ๋‹ค. + // - ๊ธฐ์ˆ ์ ์œผ๋กœ ๋งํ•˜์ž๋ฉด, ์ด๊ฒƒ์€ RefObject๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. + const divRef = useRef(null); + + useEffect(() => { + // ref.current๊ฐ€ null์ผ ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์ฃผ์˜ํ•˜์„ธ์š”. + // ์ด๊ฒƒ์€ ๋‹น์‹ ์ด ์กฐ๊ฑด์— ๋”ฐ๋ผ์„œ ref๋œ(ref-ed) element๋ฅผ renderํ•˜๊ฑฐ๋‚˜ + // ํ• ๋‹นํ•˜๋Š” ๊ฒƒ์„ ์žŠ์„ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์˜ˆ์ธกํ•  ์ˆ˜ ์žˆ๋Š” ํ˜„์ƒ์ž…๋‹ˆ๋‹ค. + if (!divRef.current) throw Error("divRef is not assigned"); + + // ์ด์ œ divRef.current๋Š” ํ™•์‹คํ•˜๊ฒŒ HTMLDivElement ์ž…๋‹ˆ๋‹ค. + doSomethingWith(divRef.current); + }); + + // React๊ฐ€ ๋‹น์‹ ์„ ์œ„ํ•ด ref๋ฅผ ๊ด€๋ฆฌํ•  ์ˆ˜์žˆ๋„๋ก element์—๊ฒŒ ref๋ฅผ ์ „๋‹ฌํ•ด ์ฃผ์„ธ์š”. + return
etc
; +} +``` + +๋งŒ์•ฝ `divRef.current`๊ฐ€ ์ ˆ๋Œ€๋กœ null์ด ์•„๋‹๊ฒƒ์ด๋ผ๋Š” ๊ฒƒ์„ ํ™•์‹ ํ•œ๋‹ค๋ฉด, non-null assertion operator `!`์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. : + +```tsx +const divRef = useRef(null!); +// ๋‚˜์ค‘์—... ์ด๊ฒƒ์ด null ์ธ์ง€ ํ™•์ธํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. +doSomethingWith(divRef.current); +``` + +๋‹น์‹ ์ด type safety๊ฐ€ ๋ณด์žฅ๋œ๋‹ค๊ณ  ๋ฏธ๋ฆฌ ๊ฐ€์ •ํ•˜๊ณ  ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•œ๋‹ค๋Š” ๊ฒƒ์— ์ฃผ์˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋ Œ๋”๋ง ๊ณผ์ •์—์„œ ref๋ฅผ element์— ํ• ๋‹นํ•˜๋Š” ๊ฒƒ์„ ์žŠ๊ฑฐ๋‚˜, ref๋œ(ref-ed) element๊ฐ€ ์กฐ๊ฑด๋ถ€ ๋ Œ๋”๋ง ๋œ๋‹ค๋ฉด runtime error๊ฐ€ ๋ฐœ์ƒํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. + +
+Tip: ์–ด๋–ค HTMLElement๋ฅผ ์‚ฌ์šฉํ• ์ง€ ์„ ํƒํ•˜๊ธฐ + +Ref๋Š” ๋ช…์‹œ์„ฑ(specificity)์„ ํ•„์š”๋กœ ํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰, `HTMLElement` ๋งŒ์„ ๋ช…์‹œํ•˜๋Š” ๊ฒƒ์€ ์ถฉ๋ถ„ํ•˜์ง€ ์•Š๋‹ค๋Š” ๋ง์ž…๋‹ˆ๋‹ค. ๋งŒ์•ฝ ๋‹น์‹ ์ด ํ•„์š”ํ•œ element type์˜ ์ด๋ฆ„์„ ๋ชจ๋ฅธ๋‹ค๋ฉด, [lib.dom.ts](https://github.com/microsoft/TypeScript/blob/v3.9.5/lib/lib.dom.d.ts#L19224-L19343)์—์„œ ํ™•์ธํ•˜๊ฑฐ๋‚˜ ์˜๋„์ ์œผ๋กœ type error๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๊ณ  language service๊ฐ€ type์˜ ์ด๋ฆ„์„ ์•Œ๋ ค์ฃผ๋„๋ก ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +![image](https://user-images.githubusercontent.com/6764957/116914284-1c436380-ac7d-11eb-9150-f52c571c5f07.png) + +
+ +##### Option 2: Mutable value ref + +**[mutable value๋ฅผ ๊ฐ€์ง€๊ธฐ ์œ„ํ•ด์„œ๋Š”](https://reactjs.org/docs/hooks-faq.html#is-there-something-like-instance-variables):** ์›ํ•˜๋Š” type์„ ์‚ฌ์šฉํ•˜๊ณ  ์ดˆ๊ธฐ ๊ฐ’์ด ์™„์ „ํžˆ ํ•ด๋‹น type์— ์†ํ•˜๋Š”์ง€ ํ™•์ธํ•˜์„ธ์š”. + +```tsx +function Foo() { + // ๊ธฐ์ˆ ์ ์œผ๋กœ ๋งํ•˜์ž๋ฉด, ์ด๊ฒƒ์€ MutableRefObject์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. + const intervalRef = useRef(null); + + // ๋‹น์‹ ์ด ์ง์ ‘ ref๋ฅผ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค. (์ด๊ฒƒ์ด MutableRefObject๋ผ๊ณ  ๋ถˆ๋ฆฌ๋Š” ์ด์œ ์ด์ฃ .) + useEffect(() => { + intervalRef.current = setInterval(...); + return () => clearInterval(intervalRef.current); + }, []); + + // ref๋Š” element์˜ "ref" prop์œผ๋กœ ์ „๋‹ฌ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. + return ; +} +``` + +##### ๋‹ค์Œ์˜ ์ž๋ฃŒ๋„ ํ™•์ธํ•ด ๋ณด์„ธ์š”. + +- [@rajivpunjabi๊ฐ€ ์ž‘์„ฑํ•œ ๊ด€๋ จ ์ด์Šˆ](https://github.com/typescript-cheatsheets/react/issues/388) - [Playground](https://www.typescriptlang.org/play#code/JYWwDg9gTgLgBAKjgQwM5wEoFNkGN4BmUEIcARFDvmQNwCwAUI7hAHarwCCYYcAvHAAUASn4A+OAG9GjOHAD0CBLLnKGcxHABiwKBzgQwMYGxS4WUACbBWAczgwIcSxFwBXEFlYxkxtgDoVTQBJVmBjZAAbOAA3KLcsOAB3YEjogCNE1jc0-zgAGQBPG3tHOAAVQrAsAGVcKGAjOHTCuDdUErhWNgBabLSUVFQsWBNWA2qoX2hA9VU4AGFKXyx0AFk3H3TIxOwCOAB5dIArLHwgpHcoSm84MGJJmFbgdG74ZcsDVkjC2Y01f7yFQsdjvLAEACM-EwVBg-naWD2AB4ABLlNb5GpgZCsACiO083jEgn6kQAhMJ6HMQfpKJCFpE2IkBNg8HCEci0RisTj8VhCTBiaSKVSVIoAaoLnBQuFgFFYvFEikBpkujkMps4FgAB7VfCdLmY7F4gleOFwAByEHg7U63VYfXVg2Go1MhhG0ygf3mAHVUtF6jgYLtwUdTvguta4Bstjs9mGznCpVcbvB7u7YM90B8vj9vYgLkDqWxaeCAEzQ1n4eHDTnoo2801EknqykyObii5SmpnNifA5GMZmCzWOwOJwudwC3xjKUyiLROKRBLJf3NLJO9KanV64xj0koVifQ08k38s1Sv0DJZBxIx5DbRGhk6J5Nua5mu4PEZPOAvSNgsgnxsHmXZzIgRZyDSYIEAAzJWsI1k+BCovWp58gKcAAD5qmkQqtqKHbyCexoYRecw7IQugcAs76ptCdIQv4KZmoRcjyMRaGkU28A4aSKiUXAwwgpYtEfrcAh0mWzF0ax7bsZx3Lceetx8eqAlYPAMAABa6KJskSXAdKwTJ4kwGxCjyKy-bfK05SrDA8mWVagHAbZeScOY0CjqUE6uOgqDaRAOSfKqOYgb8KiMaZ9GSeCEIMkyMVyUwRHWYc7nSvAgUQEk6AjMQXpReWyWGdFLHeBZHEuTCQEZT8xVwaV8BxZCzUWZQMDvuMghBHASJVnCWhTLYApiH1chIqgxpGeCfCSIxAC+Yj3o+8YvvgSLyNNOLjeBGhTTNdLzVJy3reGMBbTtrB7RoB3XbNBAneCsHLatcbPhdV3GrdB1WYhw3IKNZq-W2DCLYRO7QPAljgsgORcDwVJAA) +- [Stefan Baumgartner์˜ ์˜ˆ์‹œ](https://fettblog.eu/typescript-react/hooks/#useref) - [Playground](https://www.typescriptlang.org/play/?jsx=2#code/JYWwDg9gTgLgBAJQKYEMDG8BmUIjgIilQ3wFgAoCzAVwDsNgJa4AVJADxgElaxqYA6sBgALAGIQ01AM4AhfjCYAKAJRwA3hThwA9DrjBaw4CgA2waUjgB3YSLi1qp0wBo4AI35wYSZ6wCeYEgAymhQwGDw1lYoRHCmEBAA1oYA5nCY0HAozAASLACyADI8fDAAoqZIIEi0MFpwaEzS8IZllXAAvIjEMAB0MkjImAA8+cWl-JXVtTAAfEqOzioA3A1NtC1wTPIwirQAwuZoSV1wql1zGg3aenAt4RgOTqaNIkgn0g5ISAAmcDJvBA3h9TsBMAZeFNXjl-lIoEQ6nAOBZ+jddPpPPAmGgrPDEfAUS1pG5hAYvhAITBAlZxiUoRUqjU6m5RIDhOi7iIUF9RFYaqIIP9MlJpABCOCAUHJ0eDzm1oXAAGSKyHtUx9fGzNSacjaPWq6Ea6gI2Z9EUyVRrXV6gC+DRtVu0RBgxuYSnRIzm6O06h0ACpIdlfr9jExSQyOkxTP5GjkPFZBv9bKIDYSmbNpH04ABNFD+CV+nR2636kby+BETCddTlyo27w0zr4HycfC6L0lvUjLH7baHY5Jas7BRMI7AE42uYSUXed6pkY6HtMDulnQruCrCg2oA) From d9a433d038477dda46ca110c4a17da21c4ff8c96 Mon Sep 17 00:00:00 2001 From: Seong-Jin Kim Date: Sun, 18 Sep 2022 05:42:45 +0900 Subject: [PATCH 25/25] =?UTF-8?q?docs:=20class-components=20section=20?= =?UTF-8?q?=EA=B9=8C=EC=A7=80=20=EB=B2=88=EC=97=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 298 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 298 insertions(+) diff --git a/README.md b/README.md index 7b3e607..06b9c22 100644 --- a/README.md +++ b/README.md @@ -460,3 +460,301 @@ function Foo() { - [@rajivpunjabi๊ฐ€ ์ž‘์„ฑํ•œ ๊ด€๋ จ ์ด์Šˆ](https://github.com/typescript-cheatsheets/react/issues/388) - [Playground](https://www.typescriptlang.org/play#code/JYWwDg9gTgLgBAKjgQwM5wEoFNkGN4BmUEIcARFDvmQNwCwAUI7hAHarwCCYYcAvHAAUASn4A+OAG9GjOHAD0CBLLnKGcxHABiwKBzgQwMYGxS4WUACbBWAczgwIcSxFwBXEFlYxkxtgDoVTQBJVmBjZAAbOAA3KLcsOAB3YEjogCNE1jc0-zgAGQBPG3tHOAAVQrAsAGVcKGAjOHTCuDdUErhWNgBabLSUVFQsWBNWA2qoX2hA9VU4AGFKXyx0AFk3H3TIxOwCOAB5dIArLHwgpHcoSm84MGJJmFbgdG74ZcsDVkjC2Y01f7yFQsdjvLAEACM-EwVBg-naWD2AB4ABLlNb5GpgZCsACiO083jEgn6kQAhMJ6HMQfpKJCFpE2IkBNg8HCEci0RisTj8VhCTBiaSKVSVIoAaoLnBQuFgFFYvFEikBpkujkMps4FgAB7VfCdLmY7F4gleOFwAByEHg7U63VYfXVg2Go1MhhG0ygf3mAHVUtF6jgYLtwUdTvguta4Bstjs9mGznCpVcbvB7u7YM90B8vj9vYgLkDqWxaeCAEzQ1n4eHDTnoo2801EknqykyObii5SmpnNifA5GMZmCzWOwOJwudwC3xjKUyiLROKRBLJf3NLJO9KanV64xj0koVifQ08k38s1Sv0DJZBxIx5DbRGhk6J5Nua5mu4PEZPOAvSNgsgnxsHmXZzIgRZyDSYIEAAzJWsI1k+BCovWp58gKcAAD5qmkQqtqKHbyCexoYRecw7IQugcAs76ptCdIQv4KZmoRcjyMRaGkU28A4aSKiUXAwwgpYtEfrcAh0mWzF0ax7bsZx3Lceetx8eqAlYPAMAABa6KJskSXAdKwTJ4kwGxCjyKy-bfK05SrDA8mWVagHAbZeScOY0CjqUE6uOgqDaRAOSfKqOYgb8KiMaZ9GSeCEIMkyMVyUwRHWYc7nSvAgUQEk6AjMQXpReWyWGdFLHeBZHEuTCQEZT8xVwaV8BxZCzUWZQMDvuMghBHASJVnCWhTLYApiH1chIqgxpGeCfCSIxAC+Yj3o+8YvvgSLyNNOLjeBGhTTNdLzVJy3reGMBbTtrB7RoB3XbNBAneCsHLatcbPhdV3GrdB1WYhw3IKNZq-W2DCLYRO7QPAljgsgORcDwVJAA) - [Stefan Baumgartner์˜ ์˜ˆ์‹œ](https://fettblog.eu/typescript-react/hooks/#useref) - [Playground](https://www.typescriptlang.org/play/?jsx=2#code/JYWwDg9gTgLgBAJQKYEMDG8BmUIjgIilQ3wFgAoCzAVwDsNgJa4AVJADxgElaxqYA6sBgALAGIQ01AM4AhfjCYAKAJRwA3hThwA9DrjBaw4CgA2waUjgB3YSLi1qp0wBo4AI35wYSZ6wCeYEgAymhQwGDw1lYoRHCmEBAA1oYA5nCY0HAozAASLACyADI8fDAAoqZIIEi0MFpwaEzS8IZllXAAvIjEMAB0MkjImAA8+cWl-JXVtTAAfEqOzioA3A1NtC1wTPIwirQAwuZoSV1wql1zGg3aenAt4RgOTqaNIkgn0g5ISAAmcDJvBA3h9TsBMAZeFNXjl-lIoEQ6nAOBZ+jddPpPPAmGgrPDEfAUS1pG5hAYvhAITBAlZxiUoRUqjU6m5RIDhOi7iIUF9RFYaqIIP9MlJpABCOCAUHJ0eDzm1oXAAGSKyHtUx9fGzNSacjaPWq6Ea6gI2Z9EUyVRrXV6gC+DRtVu0RBgxuYSnRIzm6O06h0ACpIdlfr9jExSQyOkxTP5GjkPFZBv9bKIDYSmbNpH04ABNFD+CV+nR2636kby+BETCddTlyo27w0zr4HycfC6L0lvUjLH7baHY5Jas7BRMI7AE42uYSUXed6pkY6HtMDulnQruCrCg2oA) + +#### useImperativeHandle + +ํ•ด๋‹น [Stackoverflow answer](https://stackoverflow.com/a/69292925/5415299)์— ๋”ฐ๋ฅด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.: + +```tsx +// Countdown.tsx + +// forwardRef๋กœ ์ „๋‹ฌ๋  handle type์„ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค +export type CountdownHandle = { + start: () => void; +}; + +type CountdownProps = {}; + +const Countdown = forwardRef((props, ref) => { + useImperativeHandle(ref, () => ({ + // start() ๋Š” ์—ฌ๊ธฐ์„œ ํƒ€์ž… ์ถ”๋ก (type inference) ๋ฉ๋‹ˆ๋‹ค + start() { + alert("Start"); + }, + })); + + return
Countdown
; +}); +``` + +```tsx +// ์ด ์ปดํฌ๋Š”ํŠธ๋Š” Countdown ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค + +import Countdown, { CountdownHandle } from "./Countdown.tsx"; + +function App() { + const countdownEl = useRef(null); + + useEffect(() => { + if (countdownEl.current) { + // start()๋Š” ์—ฌ๊ธฐ์„œ๋„ ํƒ€์ž… ์ถ”๋ก (type inference) ๋ฉ๋‹ˆ๋‹ค. + countdownEl.current.start(); + } + }, []); + + return ; +} +``` + +##### ๋‹ค์Œ์˜ ์ž๋ฃŒ๋„ ํ™•์ธํ•ด๋ณด์„ธ์š”: + +- [ForwardRefRenderFunction ์‚ฌ์šฉํ•˜๊ธฐ](https://stackoverflow.com/a/62258685/5415299) + +#### Custom Hooks + +๋งŒ์•ฝ Custom Hook์—์„œ array๋ฅผ returnํ•œ๋‹ค๋ฉด, array์˜ ๊ฐ ์œ„์น˜์—์„œ ๊ฐ๊ธฐ ๋‹ค๋ฅธ type์„ ๊ฐ€์ง€๊ธฐ๋ฅผ ์›ํ•˜๊ฒ ์ง€๋งŒ TypeScript๋Š” union type์œผ๋กœ ์ถ”๋ก ํ•  ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— ํƒ€์ž… ์ถ”๋ก ์„ ํ”ผํ•˜๊ณ  ์‹ถ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์ƒํ™ฉ์—์„œ [TS 3.4 const assertions](https://devblogs.microsoft.com/typescript/announcing-typescript-3-4/#const-assertions)์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +```tsx +import { useState } from "react"; + +export function useLoading() { + const [isLoading, setState] = useState(false); + const load = (aPromise: Promise) => { + setState(true); + return aPromise.finally(() => setState(false)); + }; + return [isLoading, load] as const; // (boolean | typeof load)[]์ด ์•„๋‹Œ [boolean, typeof load]์œผ๋กœ ์ถ”๋ก ํ•ฉ๋‹ˆ๋‹ค. +} +``` + +[TypeScript Playground์—์„œ ํ™•์ธํ•ด ๋ณด๊ธฐ](https://www.typescriptlang.org/play/?target=5&jsx=2#code/JYWwDg9gTgLgBAJQKYEMDG8BmUIjgcilQ3wFgAoCpAD0ljkwFcA7DYCZuRgZyQBkIKACbBmAcwAUASjgBvCnDhoO3eAG1g3AcNFiANHF4wAyjBQwkAXTgBeRMRgA6HklPmkEzCgA2vKQG4FJRV4b0EhWzgJFAAFHBBNJAAuODjcRIAeFGYATwA+GRs8uSDFIzcLCRgoRiQA0rgiGEYoTlj4xMdMUR9vHIlpW2Lys0qvXzr68kUAX0DpxqRm1rgNLXDdAzDhaxRuYOZVfzgAehO4UUwkKH21ACMICG9UZgMYHLAkCEw4baFrUSqVARb5RB5PF5wAA+cHen1BfykaksFBmQA) + +์ด๋Ÿฐ ๋ฐฉ๋ฒ•์œผ๋กœ, destructureํ–ˆ์„ ๋•Œ destructuregํ•œ ์œ„์น˜์— ๋”ฐ๋ผ ์˜ฌ๋ฐ”๋ฅธ type์„ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +
+๋Œ€์•ˆ: tuple return type์„ ํ‘œ๋ช…ํ•˜๊ธฐ(assert) + +๋งŒ์•ฝ [const assertions์ด ์‚ฌ์šฉํ•˜๊ธฐ ์–ด๋ ต๋‹ค๋ฉด](https://github.com/babel/babel/issues/9800), ํ•จ์ˆ˜ return type์„ ํ‘œ๋ช…(assert)ํ•˜๊ฑฐ๋‚˜ ์ •์˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +```tsx +import { useState } from "react"; + +export function useLoading() { + const [isLoading, setState] = useState(false); + const load = (aPromise: Promise) => { + setState(true); + return aPromise.finally(() => setState(false)); + }; + return [isLoading, load] as [boolean, (aPromise: Promise) => Promise]; +} +``` + +๋งŽ์€ custom hooks์„ ์ž‘์„ฑํ•œ๋‹ค๋ฉด, ์ž๋™์œผ๋กœ tuples์˜ ํƒ€์ž…์„ ๋ช…์‹œํ•ด์ฃผ๋Š” helper๋„ ํฐ ๋„์›€์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +```tsx +function tuplify(...elements: T) { + return elements; +} + +function useArray() { + const numberValue = useRef(3).current; + const functionValue = useRef(() => {}).current; + return [numberValue, functionValue]; // type is (number | (() => void))[] +} + +function useTuple() { + const numberValue = useRef(3).current; + const functionValue = useRef(() => {}).current; + return tuplify(numberValue, functionValue); // type is [number, () => void] +} +``` + +
+ +ํ•˜์ง€๋งŒ React team์€ ๋‘๊ฐœ ์ด์ƒ์˜ ๊ฐ’์„ returnํ•˜๋Š” custom hook์€ tuple ๋Œ€์‹  ์ ์ ˆํ•œ object๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ๊ถŒ์žฅํ•œ๋‹ค๋Š” ๊ฒƒ์— ์ฃผ์˜ํ•˜์„ธ์š”. + +#### ๋” ๋งŽ์€ Hooks + TypeScript ์— ๊ด€ํ•œ ์ฝ์„ ๊ฑฐ๋ฆฌ: + +- https://medium.com/@jrwebdev/react-hooks-in-typescript-88fce7001d0d +- https://fettblog.eu/typescript-react/hooks/#useref + +๋งŒ์•ฝ React Hooks library๋ฅผ ์ž‘์„ฑํ•˜๊ณ  ์žˆ๋‹ค๋ฉด, ์‚ฌ์šฉ์ž๋“ค์ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก types๋ฅผ export ํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์žŠ์ง€ ๋งˆ์„ธ์š”. + +#### React Hooks + TypeScript Libraries ์˜ˆ์‹œ: + +- https://github.com/mweststrate/use-st8 +- https://github.com/palmerhq/the-platform +- https://github.com/sw-yx/hooks + +[์ถ”๊ฐ€ํ•  ๋‚ด์šฉ์ด ์žˆ๋‚˜์š”? issue๋ฅผ ์žฅ์„ฑํ•˜์„ธ์š”!](https://github.com/typescript-cheatsheets/react/issues/new). + + + + + +#### Class Components + +TypeScript์—์„œ `React.Component`๋Š” generic type (aka `React.Component`)์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ `React.Component`์— prop๊ณผ state type parameter๋ฅผ ์ „๋‹ฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. : + +```tsx +type MyProps = { + // `interface`๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๋„ ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค + message: string; +}; +type MyState = { + count: number; // ์ด๋Ÿฐ ์‹์œผ๋กœ +}; +class App extends React.Component { + state: MyState = { + // ๋” ๋‚˜์€ ํƒ€์ž… ์ถ”๋ก ์„ ์œ„ํ•ด ์„ ํƒ์ ์œผ๋กœ ์ž‘์„ฑํ•œ ๋‘ ๋ฒˆ์งธ annotation + count: 0, + }; + render() { + return ( +
+ {this.props.message} {this.state.count} +
+ ); + } +} +``` + +[TypeScript Playground ํ™•์ธํ•ด ๋ณด๊ธฐ](https://www.typescriptlang.org/play/?jsx=2#code/JYWwDg9gTgLgBAJQKYEMDG8BmUIjgcilQ3wFgAoCmATzCTgFlqAFHMAZzgF44BvCuHAD0QuAFd2wAHYBzOAANpMJFEzok8uME4oANuwhwIAawFwQSduxQykALjjsYUaTIDcFAL4fyNOo2oAZRgUZW4+MzQIMSkYBykxEAAjFTdhUV1gY3oYAAttLx80XRQrOABBMDA4JAAPZSkAE05kdBgAOgBhXEgpJFiAHiZWCA4AGgDg0KQAPgjyQSdphyYpsJ5+BcF0ozAYYAgpPUckKKa4FCkpCBD9w7hMaDgUmGUoOD96aUwVfrQkMyCKIxOJwAAMZm8ZiITRUAAoAJTzbZwIgwMRQKRwOGA7YDRrAABuM1xKN4eW07TAbHY7QsVhsSE8fAptKWynawNinlJcAGQgJxNxCJ8gh55E8QA) + +์žฌ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ์ด๋Ÿฌํ•œ types/interfaces๋ฅผ export/import/extend ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์žŠ์ง€ ๋งˆ์„ธ์š”. + +
+์™œ state๋ฅผ ๋‘ ๋ฒˆ annotate ํ• ๊นŒ์š”? + +๋ฐ˜๋“œ์‹œ `state` class property์— annotateํ•  ํ•„์š”๋Š” ์—†์ง€๋งŒ, ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด `this.state`์— ์ ‘๊ทผํ•˜๊ฑฐ๋‚˜ state๋ฅผ ์ดˆ๊ธฐํ™” ํ•  ๋•Œ ๋” ๋‚˜์€ ํƒ€์ž… ์ถ”๋ก ์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค. + +๊ทธ ์ด์œ ๋Š” ๋‘ ๊ฐœ์˜ annotation์€ ์„œ๋กœ ๋‹ค๋ฅธ ๋ฐฉ์‹์œผ๋กœ ๋™์ž‘ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๋‘ ๋ฒˆ์งธ generic type parameter๋Š” `this.setState()`๊ฐ€ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๋™์ž‘ํ•˜๋„๋ก ํ•ด์ค๋‹ˆ๋‹ค. ์™œ๋ƒํ•˜๋ฉด ์ด ๋ฉ”์†Œ๋“œ๋Š” base class์—์„œ ์˜ค๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ปดํฌ๋„ŒํŠธ ๋‚ด์—์„œ `state`๋ฅผ ์ดˆ๊ธฐํ™” ํ•˜๋Š” ๊ฒƒ์€ base implementation์„ overrideํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ปดํŒŒ์ผ๋Ÿฌ์—๊ฒŒ ์‚ฌ์‹ค์ƒ ๋‹ค๋ฅธ ์ž‘์—…์„ ํ•˜๊ณ  ์žˆ์ง€ ์•Š๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๋ ค์ค˜์•ผ ํ•ฉ๋‹ˆ๋‹ค. (=์ปดํŒŒ์ผ๋Ÿฌ์—๊ฒŒ ์‚ฌ์‹ค์ƒ ๊ฐ™์€ ์ž‘์—…์„ ํ•˜๊ณ  ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๋ ค์ค˜์•ผ ํ•ฉ๋‹ˆ๋‹ค.) + +[์—ฌ๊ธฐ์„œ @ferdaber์˜ ์˜๊ฒฌ์„ ํ™•์ธํ•ด๋ณด์„ธ์š”](https://github.com/typescript-cheatsheets/react/issues/57). + +
+ +
+ readonly๋Š” ํ•„์š” ์—†๋‹ค + +์ข…์ข… ์ƒ˜ํ”Œ ์ฝ”๋“œ์— props์™€ state๊ฐ€ ๋ณ€ํ•  ์ˆ˜ ์—†๋‹ค๊ณ  ํ‘œ์‹œํ•˜๊ธฐ ์œ„ํ•ด `readonly`๋ฅผ ํฌํ•ฉํ•˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +```tsx +type MyProps = { + readonly message: string; +}; +type MyState = { + readonly count: number; +}; +``` + +`React.Component`๊ฐ€ ์ด๋ฏธ props์™€ state๊ฐ€ ๋ณ€ํ•  ์ˆ˜ ์—†๋‹ค๊ณ  ํ‘œ์‹œํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ถ”๊ฐ€์ ์œผ๋กœ readonlyํ‘œ์‹œ๋ฅผ ํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ([PR ๊ณผ discussion์„ ํ™•์ธํ•˜์„ธ์š”!](https://github.com/DefinitelyTyped/DefinitelyTyped/pull/26813)) + +
+ +**Class Methods**: ์›๋ž˜ ํ•˜๋˜๋ฐ๋กœ ํ•˜๋˜, ๋‹น์‹ ์˜ ํ•จ์ˆ˜๋ฅผ ์œ„ํ•œ ๋ชจ๋“  arguments๋Š” type์ด ์žˆ์–ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ๋งŒ ๊ธฐ์–ตํ•˜์„ธ์š”. + +```tsx +class App extends React.Component<{ message: string }, { count: number }> { + state = { count: 0 }; + render() { + return ( +
this.increment(1)}> + {this.props.message} {this.state.count} +
+ ); + } + increment = (amt: number) => { + // ์ด๋Ÿฐ ์‹์œผ๋กœ + this.setState((state) => ({ + count: state.count + amt, + })); + }; +} +``` + +[TypeScript Playground์—์„œ ํ™•์ธํ•ด ๋ณด๊ธฐ](https://www.typescriptlang.org/play/?jsx=2#code/JYWwDg9gTgLgBAJQKYEMDG8BmUIjgcilQ3wFgAoCtAGxQGc64BBMMOJADxiQDsATRsnQwAdAGFckHrxgAeAN5wQSBigDmSAFxw6MKMB5q4AXwA0cRWggBXHjG09rIAEZIoJgHwWKcHTBTccAC8FnBWtvZwAAwmANw+cET8bgAUAJTe5L6+RDDWUDxwKQnZcLJ8wABucBA8YtTAaADWQfLpwV4wABbAdCIGaETKdikAjGnGHiWlFt29ImA4YH3KqhrGsz19ugFIIuF2xtO+sgD0FZVTWdlp8ddH1wNDMsFFKCCRji5uGUFe8tNTqc4A0mkg4HM6NNISI6EgYABlfzcFI7QJ-IoA66lA6RNF7XFwADUcHeMGmxjStwSxjuxiAA) + +**Class Properties**: ๋งŒ์•ฝ ๋‚˜์ค‘์— ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด class properties๋ฅผ ์„ ์–ธํ•œ๋‹ค๋ฉด, `state`์™€ ๊ฐ™์ด ์„ ์–ธํ•˜๋˜ ํ• ๋‹น์€ ํ•˜์ง€ ์•ˆ์Šต๋‹ˆ๋‹ค. + +```tsx +class App extends React.Component<{ + message: string; +}> { + pointer: number; // ์ด๋Ÿฐ ์‹์œผ๋กœ + componentDidMount() { + this.pointer = 3; + } + render() { + return ( +
+ {this.props.message} and {this.pointer} +
+ ); + } +} +``` + +[TypeScript Playground์—์„œ ํ™•์ธํ•ด ๋ณด๊ธฐ](https://www.typescriptlang.org/play/?jsx=2#code/JYWwDg9gTgLgBAJQKYEMDG8BmUIjgcilQ3wFgAoCtAGxQGc64BBMMOJADxiQDsATRsnQwAdAGFckHrxgAeAN4U4cEEgYoA5kgBccOjCjAeGgNwUAvgD44i8sshHuUXTwCuIAEZIoJuAHo-OGpgAGskOBgAC2A6JTg0SQhpHhgAEWA+AFkIVxSACgBKGzjlKJiRBxTvOABeOABmMzs4cziifm9C4ublIhhXKB44PJLlOFk+YAA3S1GxmzK6CpwwJdV1LXM4FH4F6KXKp1aesdk-SZnRgqblY-MgA) + +[์ถ”๊ฐ€ํ•  ๋‚ด์šฉ์ด ์žˆ๋‚˜์š”? issue๋ฅผ ์ƒ์„ฑํ•˜์„ธ์š”!](https://github.com/typescript-cheatsheets/react/issues/new). + +#### getDerivedStateFromProps ํƒ€์ž…ํ•‘(Typing) ํ•˜๊ธฐ + +`getDerivedStateFromProps`๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์ „์—, [documentation](https://reactjs.org/docs/react-component.html#static-getderivedstatefromprops)๊ณผ [You Probably Don't Need Derived State](https://reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html)๋ฅผ ์ฝ์–ด๋ณด์„ธ์š”. Derived State๋Š” memoization์„ ์„ค์ •ํ•œ๋Š” ๊ฒƒ์„ ๋„์šธ ์ˆ˜ ์žˆ๋Š” hooks์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ตฌํ˜„๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +๋‹ค์Œ์€ `getDerivedStateFromProps`๋ฅผ annotateํ•  ์ˆ˜ ์žˆ๋Š” ๋ช‡ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. + +1. ๋งŒ์•ฝ derived state์˜ type์„ ๋ช…์‹œ์ ์œผ๋กœ ์„ค์ •ํ–ˆ๊ณ , `getDerivedStateFromProps`์˜ return ๊ฐ’์ด ์„ค์ •ํ•œ type์„ ์ค€์ˆ˜ํ•˜๋Š”์ง€ ์•Œ๊ณ ์‹ถ์€ ๊ฒฝ์šฐ + +```tsx +class Comp extends React.Component { + static getDerivedStateFromProps(props: Props, state: State): Partial | null { + // + } +} +``` + +2. ํ•จ์ˆ˜์˜ return ๊ฐ’์ด state๋ฅผ ๊ฒฐ์ •ํ•˜๋„๋ก ํ•˜๊ณ ์‹ถ์€ ๊ฒฝ์šฐ + +```tsx +class Comp extends React.Component> { + static getDerivedStateFromProps(props: Props) {} +} +``` + +3. ๋‹ค๋ฅธ state fields์™€ derived state ๊ทธ๋ฆฌ๊ณ  memoization์„ ์›ํ•  ๊ฒฝ์šฐ + +```tsx +type CustomValue = any; +interface Props { + propA: CustomValue; +} +interface DefinedState { + otherStateField: string; +} +type State = DefinedState & ReturnType; +function transformPropsToState(props: Props) { + return { + savedPropA: props.propA, // save for memoization + derivedState: props.propA, + }; +} +class Comp extends React.PureComponent { + constructor(props: Props) { + super(props); + this.state = { + otherStateField: "123", + ...transformPropsToState(props), + }; + } + static getDerivedStateFromProps(props: Props, state: State) { + if (isEqual(props.propA, state.savedPropA)) return null; + return transformPropsToState(props); + } +} +``` + +[TypeScript Playground์—์„œ ํ™•์ธํ•ด ๋ณด๊ธฐ](https://www.typescriptlang.org/play/?jsx=2#code/JYWwDg9gTgLgBAJQKYEMDG8BmUIjgcilQ3wFgAoUSWOYAZwFEBHAVxQBs5tcD2IATFHQAWAOnpJWHMuQowAnmCRwAwizoxcANQ4tlAXjgoAdvIDcFYMZhIomdMoAKOMHTgBvCnDhgXAQQAuVXVNEB12PQtyAF9La1t7NGUAESRMKyR+AGUYFBsPLzgIGGFbHLykADFgJHZ+II0oKwBzKNjyBSU4cvzDVPTjTJ7lADJEJBgWKGMAFUUkAB5OpAhMOBgoEzpMaBBnCFcZiGGAPijMFmMMYAhjdc3jbd39w+PcmwAKXwO6IJe6ACUBXI3iIk2mwO83joKAAbpkXoEfC46KJvmA-AAaOAAehxcBh8K40DgICQIAgwAAXnkbsZCt5+LZgPDsu8kEF0aj0X5CtE2hQ0OwhG4VLgwHAkAAPGzGfhuZDoGCiRxTJBi8C3JDWBb-bGnSFwNC3RosDDQL4ov4ooGeEFQugsJRQS0-AFRKHrYT0UQaCpwQx2z3eYqlKDDaq1epwABEAEYAEwAZhjmIZUNEmY2Wx2UD2KKOw1drgB6f5fMKfpgwDQcGaE1STVZEZw+Z+xd+cD1BPZQWGtvTwDWH3ozDY7A7aP82KrSF9cIR-gBQLBUzuxhY7HYHqhq4h2ceubbryLXPdFZiQA) + +