TypeScript ์ฌ์ฉํ๊ธฐ
TypeScript๋ JavaScript ์ฝ๋ ๋ฒ ์ด์ค์ ํ์
์ ์๋ฅผ ์ถ๊ฐํ๋ ๋ฐ ๋๋ฆฌ ์ฌ์ฉ๋๋ ๋ฐฉ๋ฒ์
๋๋ค. ๊ธฐ๋ณธ์ ์ผ๋ก TypeScript๋ JSX๋ฅผ ์ง์ํ๋ฉฐ, @types/react
๋ฐ @types/react-dom
์ ์ถ๊ฐํ๋ฉด ์์ ํ React Web ์ง์์ ๋ฐ์ ์ ์์ต๋๋ค.
ํ์ต ๋ด์ฉ
์ค์น
๋ชจ๋ ํ๋ก๋์ ์์ค์ React ํ๋ ์์ํฌ๋ TypeScript ์ฌ์ฉ์ ์ง์ํฉ๋๋ค. ํ๋ ์์ํฌ๋ณ ์ค์น ๊ฐ์ด๋๋ฅผ ๋ฐ๋ฅด์ธ์.
๊ธฐ์กด React ํ๋ก์ ํธ์ TypeScript ์ถ๊ฐํ๊ธฐ
์ต์ ๋ฒ์ ์ React ํ์ ์ ์๋ฅผ ์ค์นํฉ๋๋ค.
๋ค์ ์ปดํ์ผ๋ฌ ์ต์
์ tsconfig.json
์ ์ค์ ํด์ผ ํฉ๋๋ค.
dom
์lib
์ ํฌํจ๋์ด์ผ ํฉ๋๋ค(์ฃผ์:lib
์ต์ ์ด ์ง์ ๋์ง ์์ผ๋ฉด, ๊ธฐ๋ณธ์ ์ผ๋กdom
์ด ํฌํจ๋ฉ๋๋ค).jsx
๋ฅผ ์ ํจํ ์ต์ ์ค ํ๋๋ก ์ค์ ํด์ผ ํฉ๋๋ค. ๋๋ถ๋ถ์ ์ ํ๋ฆฌ์ผ์ด์ ์์๋preserve
๋ก ์ถฉ๋ถํฉ๋๋ค. ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๊ฒ์ํ๋ ๊ฒฝ์ฐ ์ด๋ค ๊ฐ์ ์ ํํด์ผ ํ๋์งjsx
์ค๋ช ์๋ฅผ ์ฐธ์กฐํ์ธ์.
React ์ปดํฌ๋ํธ๊ฐ ์๋ TypeScript
React์ ํจ๊ป TypeScript๋ฅผ ์์ฑํ๋ ๊ฒ์ React์ ํจ๊ป JavaScript๋ฅผ ์์ฑํ๋ ๊ฒ๊ณผ ๋งค์ฐ ์ ์ฌํฉ๋๋ค. ์ปดํฌ๋ํธ๋ก ์์ ํ ๋ ๊ฐ์ฅ ์ค์ํ ์ฐจ์ด์ ์ ์ปดํฌ๋ํธ์ props์ ํ์ ์ ์ ๊ณตํ ์ ์๋ค๋ ์ ์ ๋๋ค. ์ด๋ฌํ ํ์ ์ ์๋ํฐ์์ ์ ํ์ฑ์ ๊ฒ์ฌํ๊ณ ์ธ๋ผ์ธ ๋ฌธ์๋ฅผ ์ ๊ณตํ๋ ๋ฐ ์ฌ์ฉํ ์ ์์ต๋๋ค.
๋น ๋ฅด๊ฒ ์์ํ๊ธฐ ๊ฐ์ด๋์์ ๊ฐ์ ธ์จ MyButton
์ปดํฌ๋ํธ๋ฅผ ์๋ก ๋ค์ด ๋ฒํผ์ title
์ ์ค๋ช
ํ๋ ํ์
์ ์ถ๊ฐํ ์ ์์ต๋๋ค.
function MyButton({ title }: { title: string }) { return ( <button>{title}</button> ); } export default function MyApp() { return ( <div> <h1>Welcome to my app</h1> <MyButton title="I'm a button" /> </div> ); }
์ด ์ธ๋ผ์ธ ๋ฌธ๋ฒ์ ์ปดํฌ๋ํธ์ ํ์
์ ์ ๊ณตํ๋ ๊ฐ์ฅ ๊ฐ๋จํ ๋ฐฉ๋ฒ์ด์ง๋ง, ์ค๋ช
ํ ํ๋๊ฐ ๋ง์์ง๊ธฐ ์์ํ๋ฉด ๋ค๋ฃจ๊ธฐ ์ด๋ ค์์ง ์ ์์ต๋๋ค. ๋์ , interface
๋ type
์ ์ฌ์ฉํ์ฌ ์ปดํฌ๋ํธ์ props๋ฅผ ์ค๋ช
ํ ์ ์์ต๋๋ค.
interface MyButtonProps { /** ๋ฒํผ ์์ ๋ณด์ฌ์ง ํ ์คํธ */ title: string; /** ๋ฒํผ์ด ์ํธ์์ฉํ ์ ์๋์ง ์ฌ๋ถ */ disabled: boolean; } function MyButton({ title, disabled }: MyButtonProps) { return ( <button disabled={disabled}>{title}</button> ); } export default function MyApp() { return ( <div> <h1>Welcome to my app</h1> <MyButton title="I'm a disabled button" disabled={true}/> </div> ); }
์ปดํฌ๋ํธ์ props๋ฅผ ์ค๋ช
ํ๋ ํ์
์ ์ํ๋ ๋งํผ ๋จ์ํ๊ฑฐ๋ ๋ณต์กํ ์ ์์ง๋ง, type
๋๋ interface
๋ก ์ค๋ช
๋๋ ๊ฐ์ฒด ํ์
์ด์ด์ผ ํฉ๋๋ค. TypeScript๊ฐ ๊ฐ์ฒด๋ฅผ ์ค๋ช
ํ๋ ๋ฐฉ๋ฒ์ ๋ํด ๊ฐ์ฒด ํ์
์์ ๋ฐฐ์ธ ์ ์์ต๋๋ค๋ง, ์ ๋์ธ ํ์
์ ์ฌ์ฉํ์ฌ ๋ช ๊ฐ์ง ํ์
์ค ํ๋๊ฐ ๋ ์ ์๋ prop์ ์ค๋ช
ํ๋ ๊ฒ๊ณผ ๋ ๊ณ ๊ธ ์ฌ์ฉ ์์์ ๋ํ ํ์
์์ ํ์
๋ง๋ค๊ธฐ ๊ฐ์ด๋ ์ญ์ ํฅ๋ฏธ๋ก์ธ ๊ฒ์
๋๋ค.
Hooks ์์
@types/react
์ ํ์
์ ์์๋ ๋ด์ฅ Hooks์ ๋ํ ํ์
์ด ํฌํจ๋์ด ์์ผ๋ฏ๋ก ์ถ๊ฐ ์ค์ ์์ด ์ปดํฌ๋ํธ์ ์ฌ์ฉํ ์ ์์ต๋๋ค. ์ปดํฌ๋ํธ์ ์์ฑํ ์ฝ๋๋ฅผ ๊ณ ๋ คํ๋๋ก ๋ง๋ค์ด์ก๊ธฐ ๋๋ฌธ์ ๋๋ถ๋ถ์ ๊ฒฝ์ฐ ์ถ๋ก ๋ ํ์
์ ์ป์ ์ ์์ผ๋ฉฐ, ์ด์์ ์ผ๋ก๋ ํ์
์ ์ ๊ณตํ๋ ์ฌ์ํ ์์
์ ์ฒ๋ฆฌํ ํ์๊ฐ ์์ต๋๋ค.
ํ์ง๋ง, hooks์ ํ์ ์ ์ ๊ณตํ๋ ๋ฐฉ๋ฒ์ ๋ช ๊ฐ์ง ์์๋ฅผ ๋ณผ ์ ์์ต๋๋ค.
useState
useState
hook์ ์ด๊ธฐ state๋ก ์ ๋ฌ๋ ๊ฐ์ ์ฌ์ฌ์ฉํ์ฌ ๊ฐ์ ํ์
์ ๊ฒฐ์ ํฉ๋๋ค. ์๋ฅผ ๋ค์ด
// ํ์
์ "boolean"์ผ๋ก ์ถ๋ก ํฉ๋๋ค
const [enabled, setEnabled] = useState(false);
boolean
ํ์
์ด enabled
์ ํ ๋น๋๊ณ , setEnabled
๋ boolean
์ธ์๋ boolean
์ ๋ฐํํ๋ ํจ์๋ฅผ ๋ฐ๋ ํจ์๊ฐ ๋ฉ๋๋ค. state์ ๋ํ ํ์
์ ๋ช
์์ ์ผ๋ก ์ ๊ณตํ๋ ค๋ฉด useState
ํธ์ถ์ ํ์
์ธ์๋ฅผ ์ ๊ณตํ๋ฉด ๋ฉ๋๋ค.
// ๋ช
์์ ์ผ๋ก ํ์
์ "boolean"์ผ๋ก ์ค์ ํฉ๋๋ค
const [enabled, setEnabled] = useState<boolean>(false);
์ด ๊ฒฝ์ฐ์๋ ๊ทธ๋ค์ง ์ ์ฉํ์ง ์์ง๋ง, ํ์
์ ๊ณต์ ์ํ๊ฒ ๋๋ ์ผ๋ฐ์ ์ธ ๊ฒฝ์ฐ๋ ์ ๋์ธ ํ์
์ด ์๋ ๊ฒฝ์ฐ์
๋๋ค. ์๋ฅผ ๋ค์ด ์ฌ๊ธฐ์ status
๋ ๋ช ๊ฐ์ง ๋ค๋ฅธ ๋ฌธ์์ด ์ค ํ๋์ผ ์ ์์ต๋๋ค.
type Status = "idle" | "loading" | "success" | "error";
const [status, setStatus] = useState<Status>("idle");
๋๋ State ๊ตฌ์กฐํ ์์น์์ ๊ถ์ฅํ๋ ๋๋ก, ๊ด๋ จ state๋ฅผ ๊ฐ์ฒด๋ก ๊ทธ๋ฃนํํ๊ณ ๊ฐ์ฒด ํ์ ์ ํตํด ๋ค๋ฅธ ๊ฐ๋ฅ์ฑ์ ์ค๋ช ํ ์ ์์ต๋๋ค.
type RequestState =
| { status: 'idle' }
| { status: 'loading' }
| { status: 'success', data: any }
| { status: 'error', error: Error };
const [requestState, setRequestState] = useState<RequestState>({ status: 'idle' });
useReducer
useReducer
Hook์ reducer ํจ์์ ์ด๊ธฐ state๋ฅผ ์ทจํ๋ ๋ ๋ณต์กํ Hook์
๋๋ค. reducer ํจ์์ ํ์
์ ์ด๊ธฐ state์์ ์ถ๋ก ๋ฉ๋๋ค. state์ ๋ํ ํ์
์ ์ ๊ณตํ๊ธฐ ์ํด useReducer
ํธ์ถ์ ํ์
์ธ์๋ฅผ ์ ํ์ ์ผ๋ก ์ ๊ณตํ ์ ์์ง๋ง, ๋์ ์ด๊ธฐ state์์ ํ์
์ ์ค์ ํ๋ ๊ฒ์ด ๋ ์ข์ ๊ฒฝ์ฐ๊ฐ ๋ง์ต๋๋ค.
import {useReducer} from 'react'; interface State { count: number }; type CounterAction = | { type: "reset" } | { type: "setCount"; value: State["count"] } const initialState: State = { count: 0 }; function stateReducer(state: State, action: CounterAction): State { switch (action.type) { case "reset": return initialState; case "setCount": return { ...state, count: action.value }; default: throw new Error("Unknown action"); } } export default function App() { const [state, dispatch] = useReducer(stateReducer, initialState); const addFive = () => dispatch({ type: "setCount", value: state.count + 5 }); const reset = () => dispatch({ type: "reset" }); return ( <div> <h1>Welcome to my counter</h1> <p>Count: {state.count}</p> <button onClick={addFive}>Add 5</button> <button onClick={reset}>Reset</button> </div> ); }
๋ช ๊ฐ์ง ์ฃผ์ ์์น์์ TypeScript๋ฅผ ์ฌ์ฉํ๊ณ ์์ต๋๋ค.
interface State
๋ reducer state์ ๋ชจ์์ ์ค๋ช ํฉ๋๋ค.type CounterAction
์ reducer์ dispatch ํ ์ ์๋ ๋ค์ํ ์ก์ ์ ์ค๋ช ํฉ๋๋ค.const initialState: State
๋ ์ด๊ธฐ state์ ํ์ ์ ์ ๊ณตํ๊ณ , ๊ธฐ๋ณธ์ ์ผ๋กuseReducer
์์ ์ฌ์ฉํ๋ ํ์ ๋ ์ ๊ณตํฉ๋๋ค.stateReducer(state: State, action: CounterAction): State
๋ reducer ํจ์์ ์ธ์์ ๋ฐํ ๊ฐ์ ํ์ ์ ์ค์ ํฉ๋๋ค.
initialState
์ ํ์
์ ์ค์ ํ๋ ๊ฒ๋ณด๋ค ๋ ๋ช
์์ ์ธ ๋์์ useReducer
์ ํ์
์ธ์๋ฅผ ์ ๊ณตํ๋ ๊ฒ์
๋๋ค.
import { stateReducer, State } from './your-reducer-implementation';
const initialState = { count: 0 };
export default function App() {
const [state, dispatch] = useReducer<State>(stateReducer, initialState);
}
useContext
useContext
Hook์ ์ปดํฌ๋ํธ๋ฅผ ํตํด props๋ฅผ ์ ๋ฌํ ํ์ ์์ด ์ปดํฌ๋ํธ ํธ๋ฆฌ๋ฅผ ๋ฐ๋ผ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ๋ ๊ธฐ์ ์
๋๋ค. Provider ์ปดํฌ๋ํธ๋ฅผ ์์ฑํ ๋ ์ฌ์ฉ๋๋ฉฐ, ์ข
์ข
์์ ์ปดํฌ๋ํธ์์ ๊ฐ์ ์๋นํ๋ Hook์ ์์ฑํ ๋ ์ฌ์ฉ๋ฉ๋๋ค.
context์์ ์ ๊ณตํ ๊ฐ์ ํ์
์ createContext
ํธ์ถ์ ์ ๋ฌ๋ ๊ฐ์์ ์ถ๋ก ๋ฉ๋๋ค.
import { createContext, useContext, useState } from 'react'; type Theme = "light" | "dark" | "system"; const ThemeContext = createContext<Theme>("system"); const useGetTheme = () => useContext(ThemeContext); export default function MyApp() { const [theme, setTheme] = useState<Theme>('light'); return ( <ThemeContext value={theme}> <MyComponent /> </ThemeContext> ) } function MyComponent() { const theme = useGetTheme(); return ( <div> <p>Current theme: {theme}</p> </div> ) }
์ด ๊ธฐ์ ์ ํฉ๋ฆฌ์ ์ธ ๊ธฐ๋ณธ๊ฐ์ด ์์ ๋ ํจ๊ณผ์ ์ด์ง๋ง ๊ทธ๋ ์ง ์์ ๊ฒฝ์ฐ๋ ๊ฐํน ์์ผ๋ฉฐ, ๊ทธ๋ฌํ ๊ฒฝ์ฐ null
์ด ๊ธฐ๋ณธ๊ฐ์ผ๋ก ํฉ๋ฆฌ์ ์ด๋ผ๊ณ ๋๋ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋, ํ์
์์คํ
์ด ์ฝ๋๋ฅผ ์ดํดํ ์ ์๋๋ก ํ๋ ค๋ฉด createContext
์์ ContextShape | null
์ ๋ช
์์ ์ผ๋ก ์ค์ ํด์ผ ํฉ๋๋ค.
์ด์ ๋ฐ๋ผ context ์๋น์์ ๋ํ ํ์
์์ | null
์ ์ ๊ฑฐํด์ผ ํ๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํฉ๋๋ค. ๊ถ์ฅ ์ฌํญ์ Hook์ด ๋ฐํ์์ ์กด์ฌ ์ฌ๋ถ๋ฅผ ๊ฒ์ฌํ๊ณ ์กด์ฌํ์ง ์์ ๊ฒฝ์ฐ ์๋ฌ๋ฅผ throw ํ๋ ๊ฒ์
๋๋ค.
import { createContext, useContext, useState, useMemo } from 'react';
// ์ด๊ฒ์ ๋ ๊ฐ๋จํ ์์์ด์ง๋ง, ๋ ๋ณต์กํ ๊ฐ์ฒด๋ฅผ ์์ํ ์ ์์ต๋๋ค.
type ComplexObject = {
kind: string
};
// context๋ ๊ธฐ๋ณธ๊ฐ์ ์ ํํ๊ฒ ๋ฐ์ํ๊ธฐ ์ํด ํ์
์ `| null`์ ์ฌ์ฉํ์ฌ ๋ง๋ค์ด์ง๋๋ค.
const Context = createContext<ComplexObject | null>(null);
// Hook์ ๊ฒ์ฌ๋ฅผ ํตํด `| null`์ ์ ๊ฑฐํฉ๋๋ค.
const useGetComplexObject = () => {
const object = useContext(Context);
if (!object) { throw new Error("useGetComplexObject must be used within a Provider") }
return object;
}
export default function MyApp() {
const object = useMemo(() => ({ kind: "complex" }), []);
return (
<Context value={object}>
<MyComponent />
</Context>
)
}
function MyComponent() {
const object = useGetComplexObject();
return (
<div>
<p>Current object: {object.kind}</p>
</div>
)
}
useMemo
useMemo
Hooks๋ ํจ์ ํธ์ถ๋ก๋ถํฐ memorized ๋ ๊ฐ์ ์์ฑ/์ฌ์ ๊ทผํ์ฌ, ๋ ๋ฒ์งธ ๋งค๊ฐ๋ณ์๋ก ์ ๋ฌ๋ ์ข
์์ฑ์ด ๋ณ๊ฒฝ๋ ๋๋ง ํจ์๋ฅผ ๋ค์ ์คํํฉ๋๋ค. Hook์ ํธ์ถํ ๊ฒฐ๊ณผ๋ ์ฒซ ๋ฒ์งธ ๋งค๊ฐ๋ณ์์ ์๋ ํจ์์ ๋ฐํ ๊ฐ์์ ์ถ๋ก ๋ฉ๋๋ค. Hook์ ํ์
์ธ์๋ฅผ ์ ๊ณตํ์ฌ ๋์ฑ๋ ๋ช
ํํ๊ฒ ํ ์ ์์ต๋๋ค.
// visibleTodos์ ํ์
์ filterTodos์ ๋ฐํ ๊ฐ์์ ์ถ๋ก ๋ฉ๋๋ค.
const visibleTodos = useMemo(() => filterTodos(todos, tab), [todos, tab]);
useCallback
useCallback
๋ ๋ ๋ฒ์งธ ๋งค๊ฐ๋ณ์๋ก ์ ๋ฌ๋๋ ์ข
์์ฑ์ด ๊ฐ๋ค๋ฉด ํจ์์ ๋ํ ์์ ์ ์ธ ์ฐธ์กฐ๋ฅผ ์ ๊ณตํฉ๋๋ค. useMemo
์ ๋ง์ฐฌ๊ฐ์ง๋ก, ํจ์์ ํ์
์ ์ฒซ ๋ฒ์งธ ๋งค๊ฐ๋ณ์์ ์๋ ํจ์์ ๋ฐํ ๊ฐ์์ ์ถ๋ก ๋๋ฉฐ, Hook์ ํ์
์ธ์๋ฅผ ์ ๊ณตํ์ฌ ๋์ฑ๋ ๋ช
ํํ๊ฒ ํ ์ ์์ต๋๋ค.
const handleClick = useCallback(() => {
// ...
}, [todos]);
TypeScript strict mode์์ ์์
ํ ๋ useCallback
์ ์ฌ์ฉํ๋ ค๋ฉด ์ฝ๋ฐฑ์ ๋งค๊ฐ๋ณ์๋ฅผ ์ํ ํ์
์ ์ถ๊ฐํด์ผ ํฉ๋๋ค. ์ฝ๋ฐฑ์ ํ์
์ ํจ์์ ๋ฐํ ๊ฐ์์ ์ถ๋ก ๋๊ณ , ๋งค๊ฐ๋ณ์ ์์ด๋ ํ์
์ ์์ ํ ์ดํดํ ์ ์๊ธฐ ๋๋ฌธ์
๋๋ค.
์ฝ๋ ์คํ์ผ ์ ํธ๋์ ๋ฐ๋ผ, ์ฝ๋ฐฑ์ ์ ์ํ๋ ๋์์ ์ด๋ฒคํธ ํธ๋ค๋ฌ์ ํ์
์ ์ ๊ณตํ๊ธฐ ์ํด React ํ์
์ *EventHandler
ํจ์๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
import { useState, useCallback } from 'react';
export default function Form() {
const [value, setValue] = useState("Change me");
const handleChange = useCallback<React.ChangeEventHandler<HTMLInputElement>>((event) => {
setValue(event.currentTarget.value);
}, [setValue])
return (
<>
<input value={value} onChange={handleChange} />
<p>Value: {value}</p>
</>
);
}
์ ์ฉํ ํ์ ๋ค
@types/react
package์๋ ์๋นํ ๊ด๋ฒ์ํ ํ์
์งํฉ์ด ์์ผ๋ฉฐ, React์ TypeScript๊ฐ ์ํธ์์ฉํ๋ ๋ฐฉ์์ ์ต์ํ๋ค๋ฉด ์ฝ์ด๋ณผ ๊ฐ์น๊ฐ ์์ต๋๋ค. DefinitelyTyped์ ์๋ React ํด๋์์ ์ฐพ์ ์ ์์ต๋๋ค. ์ฌ๊ธฐ์์๋ ์ข ๋ ์ผ๋ฐ์ ์ธ ํ์
๋ช ๊ฐ์ง๋ฅผ ๋ค๋ฃจ๊ฒ ์ต๋๋ค.
DOM ์ด๋ฒคํธ
React์์ DOM ์ด๋ฒคํธ๋ก ์์ ํ ๋, ์ข ์ข ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ก๋ถํฐ ์ด๋ฒคํธ์ ํ์ ์ ์ถ๋ก ํ ์ ์์ต๋๋ค. ํ์ง๋ง, ์ด๋ฒคํธ ํธ๋ค๋ฌ์ ์ ๋ฌํ ํจ์๋ฅผ ์ถ์ถํ๊ณ ์ถ์ ๋๋ ์ด๋ฒคํธ ํ์ ์ ๋ช ์์ ์ผ๋ก ์ค์ ํด์ผ ํฉ๋๋ค.
import { useState } from 'react'; export default function Form() { const [value, setValue] = useState("Change me"); function handleChange(event: React.ChangeEvent<HTMLInputElement>) { setValue(event.currentTarget.value); } return ( <> <input value={value} onChange={handleChange} /> <p>Value: {value}</p> </> ); }
React ํ์ ์๋ ์ด๋ฒคํธ์ ๋ง์ ํ์ ์ด ์์ผ๋ฉฐ, ์ ์ฒด ๋ชฉ๋ก์ DOM์์ ๊ฐ์ฅ ๋ง์ด ์ฌ์ฉ๋๋ ์ด๋ฒคํธ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํ ์ฌ๊ธฐ์์ ํ์ธํ ์ ์์ต๋๋ค.
์ฐพ๊ณ ์๋ ํ์ ์ ๊ฒฐ์ ํ ๋ ๋จผ์ ์ฌ์ฉ ์ค์ธ ์ด๋ฒคํธ ํธ๋ค๋ฌ์ ํธ๋ฒ ์ ๋ณด๋ฅผ ํ์ธํ๋ฉด, ์ด๋ฒคํธ์ ํ์ ์ด ํ์๋ฉ๋๋ค.
์ด ๋ชฉ๋ก์ ํฌํจ๋์ง ์์ ์ด๋ฒคํธ๋ฅผ ์ฌ์ฉํด์ผ ํ๋ค๋ฉด, ๋ชจ๋ ์ด๋ฒคํธ์ ๊ธฐ๋ณธ ํ์
์ธ React.SyntheticEvent
ํ์
์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
Children
์ปดํฌ๋ํธ์ ์์์ ์ค๋ช
ํ๋ ๋ฐ๋ ๋ ๊ฐ์ง ์ผ๋ฐ์ ์ธ ๊ฒฝ๋ก๊ฐ ์์ต๋๋ค. ์ฒซ ๋ฒ์งธ๋ JSX์์ ์์์ผ๋ก ์ ๋ฌํ ์ ์๋ ๋ชจ๋ ๊ฐ๋ฅํ ํ์
์ ์กฐํฉ(union)์ธ React.ReactNode
ํ์
์ ์ฌ์ฉํ๋ ๊ฒ์
๋๋ค.
interface ModalRendererProps {
title: string;
children: React.ReactNode;
}
์ด๊ฒ์ ์์์ ๋ํด ๋งค์ฐ ๊ด๋ฒ์ํ ์ ์์
๋๋ค. ๋ ๋ฒ์งธ๋ string์ด๋ number ๊ฐ์ JavaScript ์์ ๊ฐ(primitive)์ด ์๋ JSX ์๋ฆฌ๋จผํธ๋ง ์๋ React.ReactElement
ํ์
์ ์ฌ์ฉํ๋ ๊ฒ์
๋๋ค.
interface ModalRendererProps {
title: string;
children: React.ReactElement;
}
์์์ด ํน์ JSX ์๋ฆฌ๋จผํธ ํ์
์ด๋ผ๊ณ ์ค๋ช
ํ๊ธฐ ์ํด TypeScript๋ฅผ ์ฌ์ฉํ ์ ์์ผ๋ฏ๋ก, <li>
์์๋ง ํ์ฉํ๋ ์ปดํฌ๋ํธ๋ฅผ ์ค๋ช
ํ๊ธฐ ์ํด ํ์
์์คํ
์ ์ฌ์ฉํ ์ ์๋ค๋ ์ ์ ์ฃผ์ํ์ธ์.
TypeScript ํ๋ ์ด๊ทธ๋ผ์ด๋์์ ํ์
์ฒด์ปค๋ฅผ ์ฌ์ฉํ์ฌ React.ReactNode
์ React.ReactElement
์ ๋ชจ๋ ์์๋ฅผ ํ์ธํ ์ ์์ต๋๋ค.
Style Props
React์ ์ธ๋ผ์ธ ์คํ์ผ์ ์ฌ์ฉํ ๋, React.CSSProperties
๋ฅผ ์ฌ์ฉํ์ฌ style
prop์ ์ ๋ฌ๋ ๊ฐ์ฒด๋ฅผ ์ค๋ช
ํ ์ ์์ต๋๋ค. ์ด ํ์
์ ๋ชจ๋ ๊ฐ๋ฅํ CSS ํ๋กํผํฐ์ ์กฐํฉ์ด๊ณ , style
prop์ ์ ํจํ CSS ํ๋กํผํฐ๋ฅผ ์ ๋ฌํ๊ณ ์๋์ง ํ์ธํ๊ณ ์๋ํฐ์์ ์๋ ์์ฑ ๊ธฐ๋ฅ์ ์ฌ์ฉํ ์ ์๋ ์ข์ ๋ฐฉ๋ฒ์
๋๋ค.
interface MyComponentProps {
style: React.CSSProperties;
}
์ถ๊ฐ ํ์ต
์ด ๊ฐ์ด๋์์ React์์ TypeScript๋ฅผ ์ฌ์ฉํ๋ ๊ธฐ๋ณธ ์ฌํญ์ ๋ค๋ฃจ์์ง๋ง, ๋ฐฐ์ธ ๊ฒ์ด ๋ ๋ง์ต๋๋ค. ๋ฌธ์์ ๊ฐ๋ณ API ํ์ด์ง์๋ TypeScript์ ํจ๊ป ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ๋ํ ์์ธํ ์ค๋ช ์ด ํฌํจ๋์ด ์์ ์ ์์ต๋๋ค.
๋ค์ ๋ฆฌ์์ค๋ฅผ ์ถ์ฒํฉ๋๋ค.
-
TypeScript ํธ๋๋ถ์ TypeScript์ ๋ํ ๊ณต์ ๋ฌธ์๋ก, ๋๋ถ๋ถ ์ฃผ์ ์ธ์ด ๊ธฐ๋ฅ์ ๋ค๋ฃจ๊ณ ์์ต๋๋ค.
-
TypeScript ๋ฆด๋ฆฌ์ฆ ๋ ธํธ์์๋ ๊ฐ๊ฐ์ ์๋ก์ด ๊ธฐ๋ฅ์ ๋ํด ์์ธํ ์ค๋ช ํฉ๋๋ค.
-
React TypeScript ์นํธ์ํธ๋ React์ ํจ๊ป TypeScript๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด ์ปค๋ฎค๋ํฐ์์ ๊ด๋ฆฌํ๋ ์นํธ์ํธ๋ก, ์ ์ฉํ ์ฃ์ง ์ผ์ด์ค๋ฅผ ๋ง์ด ๋ค๋ฃจ๊ณ ์ด ๋ฌธ์๋ณด๋ค ๋ ํญ๋์ ์ ๋ณด๋ฅผ ์ ๊ณตํฉ๋๋ค.
-
TypeScript ์ปค๋ฎค๋ํฐ ๋์ค์ฝ๋๋ TypeScript ๋ฐ React ๋ฌธ์ ์ ๋ํด ์ง๋ฌธํ๊ณ ๋์์ ๋ฐ์ ์ ์๋ ์ข์ ๊ณณ์ ๋๋ค.