[DAY-69] React ์ฌํ(1)
๐ ํท๊ฐ๋ ธ๋ & ๋ชฐ๋๋ ๋ถ๋ถ๋ค๋ง ์ ๋ฆฌํ๋ ๋๋ง์ TIL
๐ฏ ๋ชจ๋ ๊ฐ์ ๋ด์ฉ์ ์ ์ง ์์์!
์ค๋์ ์๊ฐ์?
TypeScript ์ ๋ง ์ ๋ง ๋ฐฐ์ฐ๊ณ ์ถ์๋ค.
React์ Vue๋ถํฐ ํด์ผํ๊ธฐ์ ๊ธฐ๋ค๋ฆฌ๊ณ ์์์ง๋ง ๋๋์ด ๋๊ฐ ์๋ค.
์ง๊ธ๊น์ง ๋ง๋ ๋ชจ๋ ํ๋ก์ ํธ ๋ฆฌํฉํ ๋ง ํ ์๊ฐ์ ๋๋ฌด ์ ๋๋ค.๐
์ญ์ ์๋ก์ด๊ฑธ ๋ฐฐ์ฐ๊ณ ์ ์ฉํ๋ ๊ฒ์ ๋๋ฌด ์ฆ๊ฑฐ์
useImperativeHandle Hook
useImperativeHandle Hook
์ ํ๋ฒํ ์ปดํฌ๋ํธ ๋ด๋ถ๊ฐ ์๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋ฑ ํน์ํ ์ปดํฌ๋ํธ์ ์ฌ์ฉ๋๋ค.
ref
(forwardRef, useRef)๋ฅผ ์ด์ฉํ๋ฉด ์ฌ์ฉ์ ์ ์ ํจ์๋ฅผ ๋ง๋ค์ด ์์ ์ปดํฌ๋ํธ์ ์ ๊ณตํ ์ ์๋ค.
์ฆ ์์ ์ปดํฌ๋ํธ๊ฐ ํจ์๋ฅผ ํตํด ํ์ ์ปดํฌ๋ํธ๋ฅผ ์ ์ดํ ์ ์๊ฒ ๋๋ค.
์ฌ๊ธฐ์ useImperativeHandle Hook
์ ์ฌ์ฉํ๋ฉด, ํ์ ์ปดํฌ๋ํธ๋ฅผ ์ ์ดํ ์ฌ๋ฌ ํจ์๋ค์ ์ ์ํ ์ ์๋ค.
// forwardRef๋ก ์ ์๋ Input ์ปดํฌ๋ํธ
const inputRef = useRef();
useImperativeHandle(ref, () => {
clear: () => {
inputRef.current.value = "";
};
focus: () => {
inputRef.current.focus();
};
});
return (
<>
Input: <input ref={inputRef} />
</>
);
์ปดํฌ๋ํธ ์ฌํ
React ๊ฐ๋ฐ์๊ฐ ๊ฐ์ฅ ๋ง์ด ํ๋ ๊ณ ๋ฏผ์ ๋จ์ฐ ์ปดํฌ๋ํธ๋ ์ด๋ป๊ฒ ์ค๊ณํด์ผ ํ ๊น? ์ด๋ค.
๋จผ์ ์ํคํ ์ฒ๋ถํฐ ์ดํด๋ณด์.
์ํคํ ์ฒ์๋ ์ฌ๋ฌ ์๋ฏธ๊ฐ ์์ง๋ง, ์ฐ๋ฆฌ๊ฐ ์ผ์ ์ ํ๊ธฐ ์ํด ๋ชจ๋์ ๊ตฌํ๊ณผ ๋๋๋ ๋ฐฉ๋ฒ์ ์ ํจ์ด๋ผ๊ณ ๋งํ ์ ์๋ค.
๊ทธ๋ ๋ค๋ฉด ๋ชจ๋(์ปดํฌ๋ํธ)์์๋ ์ด๋ ํ ๋ถ๋ถ์ด ์ค์ํ ๊น? ์์ง๋์ ๊ฒฐํฉ๋๊ฐ ์๋ค
1. ์์ง๋
- ๋ชจ๋ ๋ด ํฌํจ๋ ์์๋ค์ด ์๋ก ์ฐ๊ด๋์ด ์๋ ์ ๋ ์ฆ, ๋ชจ๋ ๋ด ๊ธฐ๋ฅ๋ค์ด ํ๋์ ์ฑ ์์ผ๋ก ์ ๋ญ์ณ ์๋์ง๋ฅผ ๋ํ๋ธ๋ค.
- ๋์ ์์ง๋์ผ์๋ก ์ข์ ์ค๊ณ
- ์์ง๋๊ฐ ๋์ ์๋ก ํ๋์ ์ฑ ์์ ์ง์คํ๊ณ , ๋ ๋ฆฝ์ฑ์ ๋์ด๋ฉฐ, ์ฐ๋ฆฌ๊ฐ ์์ ํ๊ธฐ ์ํ ์์๋ฅผ ๋น ๋ฅด๊ฒ ์ฐพ์ ์ ์๋ค.
์์ง๋๋ฅผ ๋์ด๊ธฐ ์ํ ๋ฐฉ๋ฒ
- ๊ณตํต ํ์ ์์น
๊ฐ์ ์ด์ ๋ก ๋์ผํ ์์ ์ ๋ณ๊ฒฝ๋๋ ๊ธฐ๋ฅ์ ํ๋์ ๋ชจ๋๋ก ๋ฌถ์ด์ผ ํ๋ค๋ ์์น์ด๋ค.
์ฆ ๊ฐ์ฒด ์งํฅ ์์น์ธ ๋จ์ผ ์ฑ ์ ์์น์ ์ปดํฌ๋ํธ ๊ด์ ์ผ๋ก ๋ฐ๋ผ๋ณธ ๊ฒ ์ด๋ค.
ํ์ง๋ง ๊ณผํ๊ฒ ์ ์ฉํ๋ฉด ์ฌ์ฌ์ฉ์ฑ์ด ์ค์ด๋ค ์ ์๋ค.
- ๊ณตํต ์ฌ์ฌ์ฉ ์์น
๋ชจ๋ ๋ด์ ๊ธฐ๋ฅ๋ค์ ํจ๊ป ์ฌ์ฌ์ฉ์ด ๋ ์ ์์ด์ผ ํ๋ค๋ ์์น์ด๋ค.
๋ฐ๋๋ก ์ด์ผ๊ธฐํ๋ฉด ํจ๊ป ์ฌ์ฌ์ฉ์ด ๋ ์ ์๋ค๋ฉด ๋ถ๋ฆฌํด์ผ ํ๋ค๋ ๋ป์ด๋ค.
๊ณผํ๊ฒ ์ ์ฉํ๋ฉด ๊ฐ๋ฐ ์ฉ์ด์ฑ์ด ์ค์ด๋ค ์ ์๋ค.
๊ณตํต ํ์ ์์น๊ณผ ๊ณตํต ์ฌ์ฌ์ฉ ์์น์ ์๋ก ์๋ฐฐ๋๋ค๊ณ ๋งํ ์ ์๋ค.
์ฆ, ์ํฉ์ ๋ฐ๋ผ ๊ณตํต ํ์ ์์น(์ ์ ์์ ์ปดํฌ๋ํธ, ์ฌ์ฌ์ฉ์ฑ ๋ฎ์)๊ณผ ๊ณตํต ์ฌ์ฌ์ฉ ์์น(๋ง์ ์์ ์ปดํฌ๋ํธ, ์ฌ์ฌ์ฉ์ฑ ๋์)
์ด ๋ ์ฌ์ด๋ฅผ ์ ์ ํ๊ฒ ์กฐ์ ํ๋ ๊ฒ์ด ๊ฐ๋ฐ์์ ๋ฅ๋ ฅ์ด๋ค.
2. ๊ฒฐํฉ๋
- ๋ค๋ฅธ ๋ชจ๋๊ณผ์ ์์กด์ฑ์ ๋ํ ์ ๋
- ๋ชจ๋๊ณผ ๋ชจ๋ ์ฌ์ด์ ๊ด๊ณ๊ฐ ์ด๋ ์ ๋์ธ๊ฐ๋ฅผ ๋ํ๋
- ๋ฎ์ ๊ฒฐํฉ๋์ผ์๋ก ์ข์ ์ค๊ณ
- ๊ฒฐํฉ๋๊ฐ ๋์ ์๋ก ์์ ์ ๋ํด ์ํฅ์ ๋ฏธ์น๋ ์ ๋๊ฐ ์ฆ๊ฐ
๊ฒฐํฉ๋๋ฅผ ๋ฎ์ถ๊ธฐ ์ํ ๋ฐฉ๋ฒ
- ์์ ๋ ์์กด์ฑ ์์น
๋ ์์ ๋ ๋ชจ๋์ ์์กดํ์๋ ์์น์ด๋ค.
์ฆ ์์กดํ๋ ๋ชจ๋์ด ์ ๊ณ , ์์กด๋๋ ๋ชจ๋์ด ๋ง์ ์๋ก ์์ ์ ์ธ ๋ชจ๋(์ปดํฌ๋ํธ)์ด๋ค.
์์ ์ฑ ์งํ๋ Fan-out / (Fan-in + Fan-out)
์ผ๋ก ๊ณ์ฐ์ด ๊ฐ๋ฅํ๋ค.
๋ฐ๋ผ์ 0์ ๊ฐ๊น์ธ์๋ก ์์ ๋๊ณ 1์ ๊ฐ๊น์ธ์๋ก ๋ถ์์ ํ ์ปดํฌ๋ํธ์ด๋ค.
Fan-out : ์์กด๋๋ ๊ฒ / Fan-in: ์์กดํ๋ ๊ฒ
- ์์ ๋ ์ถ์ํ ์์น
์ปดํฌ๋ํธ๋ ์์ ๋ ๋งํผ ์ถ์์ ์ด์ด์ผ ํ๋ค๋ ์์น์ด๋ค.
์ฆ ์ปดํฌ๋ํธ์ ์์ ์ฑ์ด 0์ ๊ฐ๊น์ธ์๋ก, ์ถ์์ฑ์ 1์ ๊ฐ๊น์์ผ ํ๋ค.
์ถ์์ฑ์ ์ถ์ ํด๋์ค ์ / ํด๋์ค ์
๋ก ๊ณ์ฐํ๋ค.
(ํ์ง๋ง React ์ปดํฌ๋ํธ๋ UI ์์๊ฐ ํฌํจ๋์ด์์ด ํด๋น ๊ณต์์ ์ ์ฉํ ์๋ ์๋ค.)
// ์ด๋ ํ ๊ฒ๋ ๋ค์ด์ฌ ์ ์๋ ์ถ์์ ์ธ ์ปดํฌ๋ํธ ์์
const CanBeAnything = ({ children }) => {
return <Fragment>{children}</Fragment>;
};
3. ์ปดํฌ๋ํธ ๋จ์
์ข์ ์ปดํฌ๋ํธ๊ฐ ๊ฐ์ ธ์ผ ํ๋ ์์ง๋์ ๊ฒฐํฉ๋์ ๋ํด ์์๋ดค๋ค.
๊ทธ๋ ๋ค๋ฉด ์ด๋ค ๋จ์๋ก ์ปดํฌ๋ํธ๋ฅผ ๋๋ ์ผ ํ ๊น?
ํ๋ก ํธ๋ ๋ณํ๊ฐ ํฐ ์ํํธ์จ์ด์ด๋ค. ์ฆ ๋ฐฑ์๋์ฒ๋ผ ๊ธฐ๋ฅ, ๋๋ฉ์ธ ๋จ์๋ก ๋ ์ด์ด๋ฅผ ๋๋๊ธฐ ์ ๋งคํ๋ค.
๋ฐ๋ผ์ ์ฌ๋งํ๋ฉด ์ถ์ํ ๋จ์(Tag, Style)๋ก ๋๋๋ ๊ฒ์ด ํธํ๋ค.
TypeScript
ํ์ ์คํฌ๋ฆฝํธ๋ ๋ง์ดํฌ๋ก์ํํธ์์ ๋ง๋ค์๊ณ , ๋ง ๊ทธ๋๋ก ํ์ ์ด ์ ์ฉ๋ ์๋ฐ์คํฌ๋ฆฝํธ๋ผ๋ ์๋ฏธ์ด๋ค.
1. ์ฅ์
- ํ์ ์ด ์กด์ฌํ๋ฉด ์ปดํ์ผ ๋จ๊ณ์์ ๋ฏธ๋ฆฌ ์ค๋ฅ๋ฅผ ๊ฐ์งํ ์ ์์ผ๋ฏ๋ก ์์ ์ฑ์ ๊ฐ์ง๋ค.
- ํ์ ์ ๋ณด๊ณ ํด๋น ๋ก์ง์ด ์ด๋ค ์ผ์ ํ๋์ง ๋ฏธ๋ฆฌ ์ ์ ์์ด ๊ฐ๋ ์ฑ์ด ์ข๋ค.
2. ๋จ์
- ์ด๊ธฐ ์ค์ ์ด ํ์ํ๋ค.
- ํ์ ์ด ๊ฐ์ ์ ์ด๋ค๋ณด๋, ์คํฌ๋ฆฝํธ ์ธ์ด์ ์ ์ฐ์ฑ์ด ๋ฎ์์ง๋ค.
- ์ปดํ์ผ ์๊ฐ์ด ๊ธธ์ด์ง ์ ์๋ค.
TypeScript ๋ฌธ๋ฒ
1. ํ์ ์ฃผ์๊ณผ ํ์ ์ถ๋ก
ํ์ ์ฃผ์์ ๋ณ์, ์์ ํน์ ๋ฐํ ๊ฐ์ด ๋ฌด์จ ํ์ ์ธ์ง๋ฅผ ๋ํ๋ด๋ ๊ฒ์ ์๋ฏธํ๋ค.
ํ์ ์ถ๋ก ์ ํด๋น ๋ณ์๊ฐ ์ด๋ค ํ์ ์ธ์ง ์ถ๋ก ํ๋ ๊ฒ์ด๋ค. (์ด๋ฅผ ์๋ตํ๋ฉด ์ปดํ์ผ ํ์์ ์์๋ธ๋ค.)
// 1. ํ์
์ฃผ์
let a: number = 1;
let b: boolean = false;
let c: string = "TypeScript";
let arr: number[] = []; // number ํ์
์ ๋ณ์๋ง ๋ฐฐ์ด์ ๋ฃ์ ์ ์๋ค.
let i: "good" = "good"; // i๋ผ๋ ๋ณ์๋ 'good'์ ๋ฌธ์์ด๋ง ๋ค์ด๊ฐ ์ ์๋ค.
let h: any = 3; // ์๋ฌด ๊ฐ์ด๋ ๋ค์ด๊ฐ ์ ์๋ค.
function add(a: number, b: number): number {
return a + b;
}
// 2. ํ์
์ถ๋ก (number ํ์
์์ ์ ์ ์๋ค.)
let b = 2;
2. ์ธํฐํ์ด์ค
๊ฐ์ฒด์ ํ์
์ ์ ์ํ๋ ๋ฐฉ๋ฒ์ด๋ค. interface
๋ผ๋ ํค์๋๋ก ๊ฐ๋ฅํ๋ค.
interface Company {
name: string;
age: number;
address?: string; // ์ ํ ์์ฑ(Optional)
}
const programmers: Company = {
// ๋ฌด์กฐ๊ฑด name, age๊ฐ ๋ค์ด๊ฐ๋ค.
// ๋ค๋ง address๋ ์ ํ ์์ฑ์ด๋ฏ๋ก undefined๊ฐ ๋ค์ด๊ฐ ์ ์๋ค.
};
๋ํ ์ ์ ํ ๋ฐ๋ก ๊ฐ์ ํ ๋นํ ์ ์๋ ์ต๋ช ์ธํฐํ์ด์ค๋ ์ฌ์ฉํ ์ ์๋ค.
์ฝ๋ ๋ด์ ๋ฑ ํ๋ฒ๋ง ์ฌ์ฉ๋๋ค๋ฉด ํด๋น ํ์์ ์ฌ์ฉํ๋ ๊ฒ์ด ๋ ๊น๋ํ๋ค.
const person: {
name: string;
age?: number;
} = {
name: "Jung Ji Young",
age: 25,
};
3. tuple
๋ฐฐ์ด์ Tuple๋ก ์ด์ฉํ๋ ๋ฐฉ๋ฒ์ด ์๋ค.
const tuple: [string, number] = ["JiYoung", 25];
4. enum
์ด๊ฑฐํ์ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ด๋ค.
enum Color = {
RED, // 0
ORANGE, // 1
YELLOW // 2
} // RED = 'red' ๋ฑ์ผ๋ก ์ปค์คํ
ํ ์ ์๋ค.
const color = Color.YELLOW; // 2
5. ๋์ ํ์
์ฌ๋ฌ ์๋ฃํ์ ๊ฐ์ ๊ฐ์ง ์ ์๊ฒ ํ๋ ๋ฐฉ๋ฒ์ด๋ค.
ํฉ์งํฉ ํ์ ๊ณผ ๊ต์งํฉ ํ์ ์ด ์๋ค.
// 1. ํฉ์งํฉ ํ์
let numOrStr: number | string = 1; // number ๋๋ string์ ๋ฃ์ ์ ์๋ค.
// 2. ๊ต์งํฉ ํ์
// ํ๋์ ๋ณ์๊ฐ number์ด๊ณ string์ผ ์๋ ์๋ค. ์ฆ ์์ ํ์
์์ ์ฌ์ฉ์ด ๋ถ๊ฐ๋ฅํ๋ค.
interface Name {
name: string;
}
interface Age {
age: number;
}
let Jiyoung: Name & Age = {
// Name, Age ๋ ๋ค ๋ฃ์ด์ค์ผ ํ๋ค.
name: "Jung JiYoung",
age: 25,
};
type Person = Name & Age; // ์๋ก์ด ํ์
์ ๋ง๋ค์ด ๋ผ ์ ์๋ค.
6. Optional
์ ํ ์์ฑ์ ๋ง๋ค ์ ์์ผ๋ฉฐ, ์์ฑ๋์ง ์์ ๋ฐ์ดํฐ์ ๋ํด ์์ธ์ฒ๋ฆฌ๋ฅผ ํด์ค ์ ์๋ค.
interface Post {
title: string;
content: string;
}
interface ResponseData {
post?: Post;
message?: string;
status: number;
}
const response: ResponseData[] = {
{
post: {
title: 'Hello',
content: 'How are you?'
},
status: 200
},
{
message: 'Server Error',
status: 500
}
}
console.log(response[1].post?.title);
// title์ด ์์ด๋ ์ค๋ฅ๊ฐ ๋์ง ์๊ณ undefined๊ฐ ์ถ๋ ฅ๋๋ค.
// ์ฆ ๋ฐ์ดํฐ๊ฐ ์๋ค๋ฉด ์๋์ผ๋ก undefined๋ฅผ ๋ฐํํ๋ ์๋ฏธ์ด๋ค.
7. Generic
ํ๋์ ์ธํฐํ์ด์ค๋ก ์ฌ๋ฌ ํ์ ์ ์ด์ฉํ ์ ์๊ฒ ํ๋ ๋ฐฉ๋ฒ
interface Value<T> {
value: T;
}
const value: Value<number> = {
value: 1,
};
const value: Value<string> = {
value: "1",
};
์ ๋ค๋ฆญ์ ํจ์์๋ ์ด์ฉํ ์ ์๋ค.
function toString<T>(a: T): string {
return `${a}`;
}
console.log(toString<number>(5));
8. Partial, Required, Pick, Omit
๊ธฐ์กด interface๋ฅผ ์ฌํ์ฉ ํ ์ ์๊ฒ ํด์ค๋ค.
interface User {
id: number;
name: string;
age: number;
createdAt?: string;
updatedAt?: string;
}
// 1. partial: ๋ชจ๋ ํ๋๋ฅผ Optional๋ก ๋ง๋ค์ด์ค๋ค.
const partial: Partial<User> = {};
// 2. Required: ๋ชจ๋ ํ๋๋ฅผ ํ์ ์์ฑ์ผ๋ก ๋ง๋ค์ด์ค๋ค.
const required: Required<User> = {
id: 1,
name: "Jiyoung",
age: 25,
createdAt: "",
updatedAt: "",
};
// 3. Pick: ํน์ ํ๋๋ง ๊ณจ๋ผ์ ์ฌ์ฉํ ์ ์๋ค.
const pick: Pick<User, "name" | "age"> = {
name: "Jiyoung",
age: 25,
};
// 4. Omit: ํน์ ํ๋๋ง ๋นผ๊ณ ์ฌ์ฉํ ์ ์๋ค.
const omit: Omit<User, "id" | "createdAt" | "updatedAt"> = {
name: "Jiyoung",
age: 25,
};
์ด 4๊ฐ์ง ๋ฌธ๋ฒ์ ์์ด์ ์ฌ์ฉํ ์ ์๋ค.
const mixed = Omit<User, 'id' | 'createdAt' | 'updatedAt'> & Pick<Partial<User>, 'age'> = {
name: '', // age๋ Optional์ด ๋ฉ๋๋ค.
}
9. extends
ํน์ ์ธํฐํ์ด์ค๋ฅผ ์์๋ฐ์ ์ธํฐํ์ด์ค๋ฅผ ํ์ฅํ ์ ์๋ค.
interface Time {
hour: number;
minute: number;
second: number;
}
// DateTime์ Time ํ๋ ์ธ์๋ ์ ์ํ ์์ฑ๋ค์ ๋ฐ์ ์ ์๋ค.
interface DateTime extends Time {
year: number;
month: number;
day: number;
}
// ์ด๋ ๊ฒ Pick, Omit, Partial, Required๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
interface CustomTime extends Pick<Time, 'hour' | 'minute'>
๋๊ธ๋จ๊ธฐ๊ธฐ