์ผ | ์ | ํ | ์ | ๋ชฉ | ๊ธ | ํ |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |
- CSS
- Python
- nextjs
- VanilaJS
- TypeScript
- HTML
- react
- JavaScript
- dart
- router
- ๋ฐฑ์ค
- ContextAPI
- ์ฝํ
- ํ์ด์ฌ
- react native
- ์คํฌ๋กค๊ตฌํ
- Redux
- Frontend
- ์ฃผ์์ฐฝํด์
- Today
- Total
JiSoo's Devlog
[์ฐ์ํ ํ์ ์คํฌ๋ฆฝํธ] 8์ฅ ๋ณธ๋ฌธ
๐ ๋ฆฌ์กํธ ์ปดํฌ๋ํธ์ ํ์
ํด๋์ค ์ปดํฌ๋ํธ ํ์
interface Component<P = {}, S = {}, SS = any> extends ComponentLifecycle<P, S, SS> {}
class Component<P, S> {
/* ~~ */
}
class PureComponent<P = {}, SS = any> extends Component<P, S, SS> {}
React.Component์ React.PureComponent์ ํ์ ์ ์๋ ์ ์ฝ๋์ ๊ฐ๊ณ P์ S๋ ๊ฐ๊ฐ props์ ์ํ๋ฅผ ์๋ฏธํ๋ค..
์ํ๊ฐ ์๋ ์ปดํฌ๋ํธ์ผ ๋๋ ์ ๋ค๋ฆญ์ ๋ ๋ฒ์งธ ์ธ์๋ก ํ์ ์ ๋๊ฒจ์ฃผ๋ฉด ์ํ์ ๋ํ ํ์ ์ ์ง์ ํ ์ ์๋ค.
ํจ์ ์ปดํฌ๋ํธ ํ์
ํจ์ ํํ์์ ์ฌ์ฉํด ํจ์ ์ปดํฌ๋ํธ ์ ์ธํ ๋ ๊ฐ์ฅ ๋ง์ด ๋ณผ ์ ์๋ ํํ๋ React.FC๋ React.VFC๋ก ํ์ ์ ์ง์ ํ๋ ๊ฒ์ด๋ค.
FC๋ FunctionComponent์ ์ฝ์๋ก React.FC์ React.VFC๋ ๋ฆฌ์กํธ์์ ํจ์ ์ปดํฌ๋ํธ์ ํ์ ์ง์ ์ ์ํด ์ ๊ณต๋๋ ํ์ ์ด๋ค.
React.FC๋ ์๋ฌต์ ์ผ๋ก children์ ํฌํจํ๊ณ ์๊ธฐ ๋๋ฌธ์ ํด๋น ์ปดํฌ๋ํธ์์ children์ ์ฌ์ฉํ์ง ์์๋ children props๋ฅผ ํ์ฉํ๋ค. ๋ฐ๋ผ์ children props๊ฐ ํ์ํ์ง ์์ ์ปดํฌ๋ํธ์์๋ ๋ ์ ํํ ํ์ ์ง์ ์ ์ํด React.VFC๋ฅผ ๋ง์ด ์ฌ์ฉํ๋ค.
ํ์ง๋ง ๋ฆฌ์กํธ v18๋ก ๋์ด์ค๋ฉด์ React.VFC๊ฐ ์ญ์ ๋๊ณ React.FC์์ children์ด ์ฌ๋ผ์ ธ์ React.FC๋ props ํ์ , ๋ฐํ ํ์ ์ ์ง์ ์ง์ ํ๋ ํํ๋ก ํ์ดํํด์ค์ผ ํ๋ค.
Children props ํ์ ์ง์
type PropsWithChildren<P> = P & { children?๏ผ ReactNode | undefined };
๋ณดํธ์ ์ธ children ํ์ ์ ReactNode | undefined ๊ฐ ๋๋ค.
ReactNode๋ ReactElement ์ธ์๋ ์ฌ๋ฌ ํ์ ์ ํฌํจํ๋ ํ์ ์ผ๋ก ๊ตฌ์ฒด์ ์ผ๋ก ํ์ดํํ๋ ์ฉ๋์๋ ์ ํฉํ์ง ์๋ค.
ํน์ ๋ฌธ์์ด๋ง ํ์ฉํ๊ณ ์ถ์ ๋๋ children์ ๋ํด ์ถ๊ฐ๋ก ํ์ดํํด์ค์ผ ํ๋ค.
children์ ๋ํ ํ์ ์ง์ ์ ๋ค๋ฅธ prop ํ์ ์ง์ ๊ณผ ๋์ผํ ๋ฐฉ์์ผ๋ก ์ง์ ํ ์ ์๋ค.
render ๋ฉ์๋์ ํจ์ ์ปดํฌ๋ํธ์ ๋ฐํ ํ์ - React.ReactElement vs JSX.Element vs React.ReactNode
interface ReactElement<P = any,
T extends string | JSXElementConstructor<any> =
| string
| JSXElementConstructor<any>
> {
type: T;
props: P;
key: Key | null;
}
๋ฆฌ์กํธ๋ ์ค์ DOM์ด ์๋๋ผ ๊ฐ์์ DOM์ ๊ธฐ๋ฐ์ผ๋ก ๋ ๋๋งํ๋๋ฐ ๊ฐ์ DOM์ ์๋ฆฌ๋จผํธ๋ ReactElement ํํ๋ก ์ ์ฅ๋๋ค.
ReactElement ํ์ ์ ๋ฆฌ์กํธ ์ปดํฌ๋ํธ๋ฅผ ๊ฐ์ฒด ํํ๋ก ์ ์ฅํ๊ธฐ ์ํ ํฌ๋งท
JSX.Element ํ์ ์ ์์ ์ฝ๋๋ฅผ ๋ณด๋ฉด ์ ์ ์๋ค์ํผ ๋ฆฌ์กํธ์ ReactElement๋ฅผ ํ์ฅํ๊ณ ์๋ ํ์ ์ด๋ฉฐ
๊ธ๋ก๋ฒ ๋ค์์คํ์ด์ค์ ์ ์๋์ด ์์ด ์ธ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์์ ์ปดํฌ๋ํธ ํ์ ์ ์ฌ์ ์ํ ์ ์๋ ์ ์ฐ์ฑ์ ์ ๊ณตํ๋ค.
๐๐ป ๊ธ๋ก๋ฒ ๋ค์์คํ์ด์ค
ํ๋ก๊ธ๋๋ฐ์์ ์๋ณ์๊ฐ ์ ์๋๋ ์ ์ญ์ ์ธ ๋ฒ์
์๋ฐ์คํฌ๋ฆฝํธ๋ ํ์ ์คํฌ๋ฆฝํธ์์๋ ๊ธฐ๋ณธ์ ์ผ๋ก ์ ์ญ ์ค์ฝํ์์ ์ ์ธ๋ ๋ณ์๋ ํจ์ ๋ฑ์ ๊ธ๋ก๋ฒ ๋ค์์คํ์ด์ค์ ์ํ๋ค.
type ReactText = string | number;
type ReactChild = ReactElement | ReactText;
type ReactFragment = {} | Iterable<ReactNode>;
type ReactNode =
| ReactChild
| ReactFragment
| ReactPortal
| boolean
| null
| undefined;
ReactElement, ReactNdoe, JSX.Element ํ์ฉํ๊ธฐ
3๊ฐ ์ ๋ถ ๋ฆฌ์กํธ์ ์์๋ฅผ ๋ํ๋ด๋ ํ์
ReactElement
JSX๊ฐ createElement ๋ฉ์๋๋ฅผ ํธ์ถํ๊ธฐ ์ํ ๋ฌธ๋ฒ
JSX๋ ๋ฆฌ์กํธ ์๋ฆฌ๋จผํธ๋ฅผ ์์ฑํ๊ธฐ ์ํ ๋ฌธ๋ฒ์ด๋ฉฐ ํธ๋์คํ์ผ๋ฌ๋ JSX ๋ฌธ๋ฒ์ createElement ๋ฉ์๋ ํธ์ถ๋ฌธ์ผ๋ก ๋ณํํด ๋ฆฌ์กํธ ์๋ฆฌ๋จผํธ๋ฅผ ์์ฑํ๋ค.
ReactNode
ReactChild ํ์ ์ ReactElement ๋ณด๋ค๋ ์ข ๋ ๋์ ๋ฒ์๋ฅผ ๊ฐ์ง๋ค.
ReactNode๋ ReactChild ์ธ์๋ boolean, null ๋ฑ ๋ ๋์ ๋ฒ์ฃผ์ ํ์ ์ ํฌํจํ๋ค.
ReactNode๋ ๋ฆฌ์กํธ์ render ํจ์๊ฐ ๋ฐํํ ์ ์๋ ๋ชจ๋ ํํ๋ฅผ ๋ด๊ณ ์๋ค.
JSX.Element
declare global {
namespace JSX {
interface Element extends React.ReactElement<any, any> {
//...
}
//...
}
}
JSX.Element๋ ReactElement์ ์ ๋ค๋ฆญ์ผ๋ก props์ ํ์ ํ๋์ ๋ํด any ํ์ ์ ๊ฐ์ง๋๋ก ํ์ฅํ๊ณ ์๋ค.
JSX.Element๋ ReactElement์ ํน์ ํ์ ์ผ๋ก props์ ํ์ ํ๋๋ฅผ any๋ก ๊ฐ์ง๋ ํ์ ์ด๋ผ๋ ๊ฒ์ ์ ์ ์๋ค.
๋ฆฌ์กํธ์์ ๊ธฐ๋ณธ HTML ์์ ํ์ ํ์ฉํ๊ธฐ
DetailedHTMLProps์ ComponentWithoutRef
HTML ํ๊ทธ ์์ฑ ํ์ ์ ํ์ฉํ๋ ๋ํ์ ์ธ ํ์ 2๊ฐ๋ ๋ฆฌ์กํธ์ DetailedHTMLProps์ ComponentPropsWithoutRef ํ์ ์ ํ์ฉํ๋ ๊ฒ
React.DetailedHTMLProps๋ฅผ ํ์ฉํ๋ ๊ฒฝ์ฐ์๋ HTML ํ๊ทธ ์์ฑ๊ณผ ํธํ๋๋ ํ์ ์ ์ ์ธํ ์ ์๋ค.
type NativeButtonProps = React.DetailedHTMLProps<
React.ButtonHTMLAttributes<HTMLButtonElement>,
HTMLButtonElement
>;
type ButtonProps = {
onClick?: NaticeButtonProps["onClick"]
};
type NativeButtonType = React.ComponentPropsWithoutRef<"button">;
type ButtonProps = {
onClick?: NativeButtonType["onClick"];
};
โจ ํ์ ์คํฌ๋ฆฝํธ๋ก ๋ฆฌ์กํธ ์ปดํฌ๋ํธ ๋ง๋ค๊ธฐ
JSX๋ก ๊ตฌํ๋ Select ์ปดํฌ๋ํธ
const Select = ({ onChange, options, selectedOption }) => {
const handlechange = (e) => {
const selected = Object.entries(options)
.find(([_, value]) => value === e.target.value)?.[0];
onChange?. (selected);
};
return (
<select
onChange={handlechange}
value={selectedOption 8& options[selectedOption]}
>
{Object.entries(options).map(([key, value]) => (
<option key={key} value={value}>
{value}
</option>
))}
</select>
);
};
์ ์ปดํฌ๋ํธ๋ ๊ฐ option์ ํค-๊ฐ ์์ ๊ฐ์ฒด๋ก ๋ฐ๊ณ ์์ผ๋ฉฐ ์ ํ๋ ๊ฐ์ด ๋ณ๊ฒฝ๋ ๋ ํธ์ถ๋๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋ฐ๋๋ก ๊ตฌํ๋์ด ์๋ค.
๋ฐ๋ผ์ ์ปดํฌ๋ํธ๋ฅผ ์ฌ์ฉํ๋ ๊ฐ๋ฐ์๊ฐ ๊ฐ ์์ฑ์ ์ด๋ค ํ์ ์ ๊ฐ์ ์ ๋ฌํด์ผ ํ ์ง ๋ช ํํ ์ ์ ์๋๋ก ์ถ๊ฐ์ ์ธ ์ค๋ช ์ด ํ์ํ๋ค.
JSDocs๋ก ์ผ๋ถ ํ์ ์ง์ ํ๊ธฐ
์ปดํฌ๋ํธ์ ์์ฑ ํ์ ์ ๋ช ์ํ๊ธฐ ์ํด JSDocs๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
JSDocs๋ฅผ ํ์ฉํ๋ฉด ์ปดํฌ๋ํธ์ ๋ํ ์ค๋ช ๊ณผ ๊ฐ ์์ฑ์ด ์ด๋ค ์ญํ ์ ํ๋์ง ๊ฐ๋จํ๊ฒ ์๋ ค์ค ์ ์๋ค.
/**
* Select ์ปดํฌ๋ํธ
* @param {Object} props - Select ์ปดํฌ๋ํธ๋ก ๋๊ฒจ์ฃผ๋ ์์ฑ
* @param {Object} props.options - { [key๏ผ string]๏ผ string } ํ์์ผ๋ก ์ด๋ฃจ์ด์ง option ๊ฐ์ฒด
* @param {string | undefined} props.selectedOption - ํ์ฌ ์ ํ๋ option์ key๊ฐ
(optional)
* @param {function} props.onChange - select ๊ฐ์ด ๋ณ๊ฒฝ๋์์ ๋ ๋ถ๋ฆฌ๋ callBack ํจ์
(optional)
* @returns {JSX.Element}
*/
const Select = //...
props ์ธํฐํ์ด์ค ์ ์ฉํ๊ธฐ
JSDocs๋ฅผ ํ์ฉํ๋ฉด ๊ฐ ์์ฑ์ ๋๋ต์ ์ธ ํ์ ๊ณผ ์ด๋ค ์ญํ ์ ํ๋์ง ํ์ ํ ์ ์์ง๋ง options๊ฐ ์ด๋ค ํ์์ ๊ฐ์ฒด๋ฅผ ๋ํ๋ด๋์ง๋ onChange์ ๋งค๊ฐ๋ณ์ ๋ฐ ๋ฐํ ๊ฐ์ ๋ํ ๊ตฌ์ฒด์ ์ธ ์ ๋ณด๋ฅผ ์๊ธฐ ์ฝ์ง ์์ ์๋ชป๋ ํ์ ์ด ์ ๋ฌ๋ ์ ์๋ ์ํ์ด ์กด์ฌํ๋ค.
์ด๋ฐ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ํ์ ์คํฌ๋ฆฝํธ๋ฅผ ์ฌ์ฉํด ์ข ๋ ์ ๊ตํ๊ณ ๊ตฌ์ฒด์ ์ธ ํ์ ์ ์ง์ ํ ์ ์๋ค.
๋ฆฌ์กํธ ์ด๋ฒคํธ
๋ฆฌ์กํธ๋ ๊ฐ์ DOM์ ๋ค๋ฃจ๋ฉด์ ์ด๋ฒคํธ๋ ๋ณ๋๋ก ๊ด๋ฆฌํ๋ค.
DOM ์๋ฆฌ๋จผํธ์ ๋ฑ๋ก๋์ด ์ฒ๋ฆฌํ๋ ์ด๋ฒคํธ ๋ฆฌ์ค๋์ ๋ฌ๋ฆฌ ๋ฆฌ์กํธ ์ปดํฌ๋ํธ์ ๋ฑ๋ก๋๋ ์ด๋ฒคํธ ๋ฆฌ์ค๋์ ๋ฌ๋ฆฌ ๋ฆฌ์กํธ ์ปดํฌ๋ํธ์ ๋ฑ๋ก๋๋ ์ด๋ฒคํธ ๋ฆฌ์ค๋๋ ์นด๋ฉ ์ผ์ด์ค๋ก ํ๊ธฐํ๋ค.
๋ฆฌ์กํธ ์ด๋ฒคํธ๋ ๋ธ๋ผ์ฐ์ ์ ๊ณ ์ ํ ์ด๋ฒคํธ์ ์์ ํ ๋์ผํ๊ฒ ๋์ํ์ง๋ ์๋๋ค.
ํ ์ ํ์ ์ถ๊ฐํ๊ธฐ
useState ๊ฐ์ ํจ์ ์ญ์ ํ์ ๋งค๊ฐ๋ณ์๋ฅผ ์ง์ ํด ์ค์ผ๋ก์จ ๋ฐํ๋๋ state ํ์ ์ ์ง์ ํด ์ค ์ ์๋ค.
๋ง์ฝ ์ ๋ค๋ฆญ ํ์ ์ ๋ช ์ํ์ง ์์ผ๋ฉด ํ์ ์คํฌ๋ฆฝํธ ์ปดํ์ผ๋ฌ๋ ์ด๊น๊ฐ์ ํ์ ์ ๊ธฐ๋ฐ์ผ๋ก state ํ์ ์ ์ถ๋ก ํ๋ค.
type Fruit = keyof typeof fruits; // 'apple' | 'banana' | 'blueberry';
const [fruit, changeFruit] = useState<Fruit | undefined>("apple");
// ์๋ฌ ๋ฐ์
const func = () => {
changeFruit ("orange”);
};
keyof typeof obj๋ ํด๋น ๊ฐ์ฒด์ ํค๊ฐ์ ์ ๋์จ ํ์ ์ผ๋ก ์ถ์ถํ๋ ํจํด์ผ๋ก ์์ฃผ ์ฌ์ฉ๋๋ค.
ํ ์ด๋ ์ธ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋๋ ๋ด๋ถ ๋ชจ๋์ ํจ์๋ ์ ์ ํ ์ ๋ค๋ฆญ ํ์ ์ ์ค์ ํด ํ์ฉํ ์ ์๋ค.
์ ๋ค๋ฆญ ์ปดํฌ๋ํธ ๋ง๋ค๊ธฐ
const FruitSelect = () => {
const [fruit, changeFruit] = useState<Fruit | undefined>();
return (
<Select onChange={changeFruit} options={fruits} selectedOption="orange" />
);
};
selectedOption์ options์ ์กด์ฌํ์ง ์๋ ๊ฐ์ ๋ฐ์๋ ์๋ฌด๋ฐ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ง ์๋๋ค.
ํจ์ ์ปดํฌ๋ํธ ์ญ์ ํจ์๋ผ์ ์ ๋ค๋ฆญ์ ์ฌ์ฉํ ์ปดํฌ๋ํธ๋ฅผ ๋ง๋ค์ด๋ผ ์ ์๋ค.
interface SelectProps<OptionType extends Record<string, string>> {
options: OptionType;
selectedOption?: keyof OptionType;
onChange?: (selected?: keyof OptionType) => void;
}
const Select = <OptionType extends Record<string, string>>({
options,
selectedOption,
onChange,
}: SelectProps<OptionType>) => {
// Select component implementation
};
์ ์ฝ๋์์๋ ๊ฐ์ฒด ํ์์ ํ์ ์ ๋ฐ์ ํด๋น ๊ฐ์ฒด์ ํค๊ฐ์ selectedOption, onChange์ ๋งค๊ฐ๋ณ์์๋ง ์ ์ฉํ๋๋ก ๋ง๋ ์์๋ค.
Select ์ปดํฌ๋ํธ์ ์ ๋ฌ๋๋ props์ ํ์ ๊ธฐ๋ฐ์ผ๋ก ํ์ ์ด ์ถ๋ก ๋์ด <Select<์ถ๋ก ๋ ํ์ >> ํํ์ ์ปดํฌ๋ํธ๊ฐ ์์ฑ๋๋ค.
HTMLAttributes, ReactProps ์ ์ฉํ๊ธฐ
className, id์ ๊ฐ์ ๋ฆฌ์กํธ ์ปดํฌ๋ํธ์ ๊ธฐ๋ณธ props๋ฅผ ์ถ๊ฐํ๋ ค๋ฉด SelectProps์ ์ง์ className?: string; id?: string;์ ๋ฃ์ด๋ ๋์ง๋ง ๋ฆฌ์กํธ์์ ์ ๊ณตํ๋ ํ์ ์ ์ฌ์ฉํ๋ฉด ๋ ์ ํํ ํ์ ์ ์ค์ ํ ์ ์๋ค.
type ReactSelectProps = React.ComponentPropsWithoutRef<"select">;
interface SelectProps<OptionType extends Record<sring, string>> {
id?: ReactSelectProps["id"];
className?: ReactSelectProps["className"];
//...
}
ComponentPropsWithoutRef๋ ๋ฆฌ์กํธ ์ปดํฌ๋ํธ์ prop ํ์ ์ ๋ฐํํด์ฃผ๋ ํ์ ์ด๋ค.
Type['key']๋ฅผ ํ์ฉํ๋ฉด ๊ฐ์ฒด ํ์์ ํ์ ๋ด๋ถ ์์ฑ๊ฐ์ ๊ฐ์ ธ์ฌ ์ ์๋ค.
ReactProps์์ ์ฌ๋ฌ ๊ฐ์ ํ์ ์ ๊ฐ์ ธ์์ผ ํ๋ค๋ฉด Pick ํค์๋๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
๊ณต๋ณ์ฑ๊ณผ ๋ฐ๊ณต๋ณ์ฑ
์ผ๋ฐ์ ์ธ ํ์ ๋ค์ ๊ณต๋ณ์ฑ์ ๊ฐ์ง๊ณ ์์ด ์ข์ ํ์ ์์ ๋์ ํ์ ์ผ๋ก ํ ๋น์ด ๊ฐ๋ฅํ๋ค.
ํ์ง๋ง ์ ๋ค๋ฆญ ํ์ ์ ์ง๋ ํจ์๋ ๋ฐ๊ณต๋ณ์ฑ์ ๊ฐ์ง๋ค.
์์ ํ ํ์ ๊ฐ๋๋ฅผ ์ํด ํน์ํ ๊ฒฝ์ฐ๋ฅผ ์ ์ธํ๊ณ ๋ ์ผ๋ฐ์ ์ผ๋ก ๋ฐ๊ณต๋ณ์ ์ธ ํจ์ ํ์ ์ ์ค์ ํ๋ ๊ฒ์ด ๊ถ์ฅ๋๋ค.
'Frontend > Typescript' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[์ฐ์ํ ํ์ ์คํฌ๋ฆฝํธ] 9์ฅ (0) | 2025.06.06 |
---|---|
[์ฐ์ํ ํ์ ์คํฌ๋ฆฝํธ] 7์ฅ (1) | 2025.06.05 |
[์ฐ์ํ ํ์ ์คํฌ๋ฆฝํธ] 6์ฅ (1) | 2025.05.29 |
[์ฐ์ํ ํ์ ์คํฌ๋ฆฝํธ] 5์ฅ (4) | 2025.05.28 |
[์ฐ์ํ ํ์ ์คํฌ๋ฆฝํธ] 4์ฅ (2) | 2025.05.23 |