๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
Web Programming/React.js

[React.js] TypeScript์—์„œ์˜ setState ๋“ฑ๋“ฑ์— ๋Œ€ํ•ด ์•Œ์•„๋ณด์ž

by Haren 2023. 10. 20.

๐Ÿค” any ์ง€์–‘ํ•˜๊ธฐ.

์กธ์—… ์ž‘ํ’ˆ์˜ ํ”„๋ก ํŠธ๋ฅผ Next.js + TypeScript๋กœ ์ž‘์„ฑํ•˜๊ณ  ์žˆ๋‹ค. 

์ž์‹ ์ปดํฌ๋„ŒํŠธ์—์„œ์˜ ์ƒํ˜ธ ์ž‘์šฉ์ด state๋ฅผ ๋ณ€๊ฒฝ์‹œ์ผœ์•ผ ํ•  ํ•„์š”๊ฐ€ ์žˆ์–ด์„œ ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ์— ์„ ์–ธ๋œ setState ํ•จ์ˆ˜๋ฅผ ์ž์‹ ์ปดํฌ๋„ŒํŠธ์— props๋กœ ๋„˜๊ฒจ์ฃผ๋ฉด์„œ ์˜๋ฌธ์ด ์ƒ๊ฒผ๋‹ค.

 

TypeScript๋ฅผ ํ†ตํ•œ React ๊ฐœ๋ฐœ์—์„œ ๋ณดํ†ต props๋ฅผ ๋„˜๊ฒจ๋ฐ›์„ ๋•Œ, interface๋‚˜ type alias๋ฅผ ํ™œ์šฉํ•˜์—ฌ ํ•ด๋‹น props์˜ ํƒ€์ž…์„ ์ง€์ •ํ•ด์ฃผ๊ณ ๋Š” ํ•˜๋Š”๋ฐ, props๋กœ number, string ๊ฐ™์€ ์›์‹œ ํƒ€์ž…๋งŒ ๋„˜๊ธฐ๋Š” ๊ฒƒ๋„ ์•„๋‹ˆ๊ณ  ๋•Œ๋•Œ๋กœ ReactNode ๊ฐ™์€ ํƒ€์ž…๋“ค๋„ ๋„˜๊ฒจ์•ผ ํ•  ํ•„์š”๊ฐ€ ์ƒ๊ธฐ๊ณ ๋Š” ํ•œ๋‹ค.

 

์ด์ „๊นŒ์ง€๋Š” ReactNode๋‚˜ HTML ์—˜๋ฆฌ๋จผํŠธ, setState ํ•จ์ˆ˜ ๋“ฑ์„ props๋กœ ๋„˜๊ฒจ์ค„ ๋•Œ์— ์ •ํ™•ํ•œ ํƒ€์ž…์„ ๋ชฐ๋ผ any๋กœ ์ง€์ •ํ•˜์—ฌ ์‚ฌ์šฉํ–ˆ๋Š”๋ฐ, ์ด๋ฒˆ ํ”„๋กœ์ ํŠธ์—์„œ๋Š” ์ง€๊ธˆ๊นŒ์ง€์˜ ์ž˜๋ชป๋œ ์Šต๊ด€์„ ๋‹ค์žก๊ณ ์ž ํƒ€์ž… ์ง€์ •์„ ์—„์ค‘ํ•˜๊ฒŒ ์ง€์ผœ๋‚˜๊ฐ€๋ฉฐ ๊ฐœ๋ฐœ์„ ํ•˜๊ณ  ์žˆ๋Š” ์ค‘์ด๋‹ค. ๋”ฐ๋ผ์„œ ์˜ค๋Š˜ ์ƒˆ๋กœ์ด ๋ฐฐ์šด ๋‚ด์šฉ์„ ์ •๋ฆฌํ•ด๋ณผ๊นŒ ํ•œ๋‹ค.

 

๐Ÿ”ฆ ๋ฌธ์ œ์˜ ์ปดํฌ๋„ŒํŠธ

interface SelectOption {
  value: number | string;
  name: string
}

interface Props {
  selectOption : SelectOption[];
  setOption: React.Dispatch<React.SetStateAction<number>>;
}

const SelectBox = ({selectOption, setOption} : Props) => {
  const onChangeHandler = (e : React.ChangeEvent<HTMLSelectElement>) => {
    setOption(parseInt(e.target.value));
  }

  return(
    <SelectStyle onChange={onChangeHandler}>
      {selectOption.map((item, index) => (
        <option key={index} value={item.value}>{item.name}</option>
      ))}
    </SelectStyle>
  );
};

SelectBox ์ปดํฌ๋„ŒํŠธ๋Š” ์šฐ๋ฆฌ์˜ ํ”„๋กœ์ ํŠธ์—์„œ ํ•™์ƒ์˜ ํ•™๋…„๋ณ„ ์ •๋ณด๋ฅผ ์„ ํƒํ•ด ๋ณด์—ฌ์ฃผ๊ธฐ ์œ„ํ•œ <select>๋ฅผ ์žฌํ™œ์šฉํ•˜๊ธฐ ์œ„ํ•ด ๋ณ„๋„๋กœ ๋ถ„๋ฆฌํ•œ ์ปดํฌ๋„ŒํŠธ๋‹ค. props๋กœ SelectOption ์ธํ„ฐํŽ˜์ด์Šค๋กœ ์ง€์ •ํ•œ ํƒ€์ž…์„ setOption์˜ ํƒ€์ž… ์ง€์ •๊ณผ ๋ณ‘ํ•ฉํ•˜์—ฌ Props ํƒ€์ž…์œผ๋กœ ํ•˜๋Š” selectOption๊ณผ setOption์„ ๋ฐ›๋Š”๋‹ค.

 

setOption์€ ์‚ฌ์šฉ์ž๊ฐ€ <select> ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ํ†ตํ•ด ๋‹ค๋ฅธ <option>์„ ์„ ํƒํ–ˆ์„ ๋•Œ ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ์—์„œ ๋ณ€๊ฒฝ๋œ ๊ฐ’์„ ๋‹ค๋ฃจ๊ธฐ ์œ„ํ•ด ๋‚ด๋ ค๋ฐ›๋Š” setState ํ•จ์ˆ˜๋‹ค.

 

์ง€๊ธˆ์—์„œ์•ผ ๋ฌผ๋ก  ์™„์„ฑ์ด ๋˜์—ˆ์œผ๋‹ˆ ์™„๋ฒฝํ•˜๊ฒŒ ํƒ€์ž… ์ง€์ •์ด ๋˜์–ด์žˆ์ง€๋งŒ, ๋นจ๊ฐ„ ์ง€๋ ์ด๋ฅผ ๋งŽ์ด ๋งŒ๋‚˜์•ผ ํ–ˆ๋‹ค.

 

๐Ÿ‘€  React.Dispatch<React.setStateAction<number>>

VSC์—์„œ๋Š” ESLint ๋“ฑ์˜ ํ™•์žฅ์„ ํ™œ์šฉํ•˜๋ฉด ๋ณด๋‹ค ํŽธ์•ˆํ•˜๊ฒŒ ๊ฐœ๋ฐœ์„ ํ•  ์ˆ˜ ์žˆ๊ณ , TypeScript์˜ ๋ฆฐํŠธ ๋˜ํ•œ ์ ์šฉ๋œ ์ƒํƒœ์ด๋ฏ€๋กœ ์‚ฌ์šฉํ•˜๋Š” ์š”์†Œ์— ์ปค์„œ๋ฅผ ์˜ฌ๋ฆฌ๋ฉด ํ•ด๋‹น ์š”์†Œ์˜ ํƒ€์ž…์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

 

์œ„์—์„œ ์„ค๋ช…ํ•œ setOption ํ•จ์ˆ˜์— ์ปค์„œ๋ฅผ ์˜ฌ๋ฆด ๊ฒฝ์šฐ ํƒ€์ž…์ด Dispatch<SetStateAction<number>> ๋ผ๊ณ  ์•Œ๋ ค์ฃผ๊ณ  ์žˆ๋‹ค.

ํ•˜์ง€๋งŒ ์ด๋ฅผ ๊ณง์ด๊ณง๋Œ€๋กœ ์ธํ„ฐํŽ˜์ด์Šค์— Dispatch<SetStateAction<number>> ๋ผ๊ณ  ๊ธฐ์ž…์„ ํ•ด์ฃผ๋ฉด

์—ฅ... ์•ˆ๋œ๋‹ค.

๊ทธ๋ž˜์„œ ReactNode ํƒ€์ž…์„ ์‚ฌ์šฉํ•  ๋•Œ, React.ReactNode ์ฒ˜๋Ÿผ namespace๋ฅผ ๋ถ™์—ฌ์ฃผ๋ฉด ํ•ด๊ฒฐ์ด ๋ ๊นŒ ์‹ถ์–ด React.Dispatch<React.SetStateAction<number>>๋กœ ์ง€์ •ํ•ด์ฃผ๋‹ˆ ์˜ค๋ฅ˜๋ฅผ ์—†์•จ ์ˆ˜ ์žˆ์—ˆ๋‹ค.

์ž˜ ํ•ด๊ฒฐ์ด ๋˜์—ˆ์ง€๋งŒ ์™œ ๋˜์—ˆ๋Š”์ง€๋ฅผ ๋ชจ๋ฅด๋‹ˆ ์ด ๋ถ€๋ถ„์— ๋Œ€ํ•ด์„œ ๋” ๊ณต๋ถ€๋ฅผ ํ•ด๋ด์•ผ๊ฒ ๋‹ค.

 

โ€ผ๏ธ event์˜ ํƒ€์ž…์€ ๋ญ˜๊นŒ?

๊ทธ๋ฆฌ๊ณ  SelectBox ์ปดํฌ๋„ŒํŠธ์—์„œ <select> ์—˜๋ฆฌ๋จผํŠธ์˜ onChange ์ด๋ฒคํŠธํ•ธ๋“ค๋Ÿฌ๋ฅผ ๊ตฌํ˜„ํ•˜๋ฉฐ ๋‹ค์‹œ ํƒ€์ž… ์ง€์ •์˜ ๋‚œ๊ด€์— ๋ด‰์ฐฉํ–ˆ๋‹ค.

๋ณดํ†ต ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ํ•จ์ˆ˜๋ฅผ ์ •์˜ํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ์ด๋ฒคํŠธ ๋งค๊ฐœ๋ณ€์ˆ˜ e, event... ๋Š” ์–ด๋–ค ํƒ€์ž…์„ ์ง€์ •์„ ํ•ด์ค˜์•ผ ํ• ๊นŒ?

 

any๋ฅผ ์ง€์–‘ํ•˜๊ณ  ์‹ถ๋‹ค๊ตฌ์š”

onClick ์ด๋ฒคํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•  ๋•Œ์—๋Š” ๋ณดํ†ต React.MouseEvent ํƒ€์ž…์„ ์‚ฌ์šฉํ•˜๊ณ ๋Š” ํ–ˆ์—ˆ๋‹ค. ๊ทธ๋ ‡๋‹ค๋ฉด onChange์—์„œ์˜ ์ด๋ฒคํŠธ ๋งค๊ฐœ๋ณ€์ˆ˜์˜ ํƒ€์ž…์€ ๊ณผ์—ฐ ๋ญ˜๊นŒ? ์ฒ˜์Œ์—๋Š” ๋‹น์—ฐํžˆ React.ChangeEvent๋กœ ์ž‘์„ฑ์„ ํ•ด๋ณด์•˜๋Š”๋ฐ...

'EventTarget & Element' ํ˜•์‹์— 'value' ์†์„ฑ์ด ์—†์Šต๋‹ˆ๋‹ค. ๋ผ๊ณ  ํ•œ๋‹ค. ์ด๋Š” Element ํƒ€์ž…์„ ์ •ํ™•ํžˆ ์ง€์ •ํ•ด์ฃผ์ง€ ์•Š์•„์„œ ๊ทธ๋Ÿฐ ๊ฒƒ ๊ฐ™๋‹ค. ๋”ฐ๋ผ์„œ <T>๋ฅผ ํ™œ์šฉํ•ด HTMLSelectElement ํƒ€์ž…์„ ์ง€์ •ํ•จ์œผ๋กœ์จ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.

์ด๊ฒƒ ์—ญ์‹œ '์ €๋ฒˆ์—๋Š” React.MouseEvent' ์˜€์œผ๋‹ˆ๊นŒ ์ด๊ฑด Change๊ฐ€ ๋“ค์–ด๊ฐ€์ง€ ์•Š์„๊นŒ?' ํ•˜๋Š” ์ƒ๊ฐ์—์„œ VSC์˜ ์ž๋™์™„์„ฑ ๊ธฐ๋Šฅ์„ ํ†ตํ•ด ํ•˜๋‚˜ํ•˜๋‚˜ ๋„ฃ์–ด๋ณด๊ณ  ์•Œ์•„๋‚ธ ๊ฑฐ๋ผ ์™œ ๋˜๋Š”์ง€๋Š” ๋ชจ๋ฅด๊ฒ ๋‹ค. ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ์— ๋“ค์–ด๊ฐˆ ์ˆ˜ ์žˆ๋Š” ํƒ€์ž… (ํŠนํžˆ ํ…œํ”Œ๋ฆฟ)์— ๋Œ€ํ•œ ํ•™์Šต์„ ๋” ํ•ด๋ด์•ผ๊ฒ ๋‹ค. React ๋„ค์ž„์ŠคํŽ˜์ด์Šค์˜ ํƒ€์ž…์„ ์“ฐ๋Š”๊ฒƒ๋„ ์ด๋ฒˆ์— ์ฒ˜์Œ ์•Œ๊ฒŒ๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์—...