[TIL] 0622 | React with Redux, Next.js, TypeScript

Teasanยท2022๋…„ 6์›” 22์ผ
0

TIL

๋ชฉ๋ก ๋ณด๊ธฐ
15/36
post-thumbnail

๋ชฉ์ฐจ

  • ํฌ์ปค์Šค๋ฅผ ์žƒ์€ ๋ฆฌ์•กํŠธ
  • ๋ฆฌํŒฉํ† ๋ง ๋ฐ State ํŒŒ์ƒ

โœง ํฌ์ปค์Šค๋ฅผ ์žƒ์€ ๋ฆฌ์•กํŠธ

  • ์šฐ๋ฆฌ๋Š” ์ง€๊ธˆ๊นŒ์ง€ form ์ด ์ œ์ถœ๋˜์—ˆ์„ ๋•Œ๋งŒ ์œ ํšจ์„ฑ์„ ๊ฒ€์ฆํ•˜๋Š” ๋ฐฉ์‹์„ ์‚ฌ์šฉํ–ˆ๋‹ค. ์•„์ง ์ž…๋ ฅ์ฐฝ์ด ํฌ์ปค์Šค ์•„์›ƒ ๋  ๋•Œ๋‚˜ ํ‚ค ์ž…๋ ฅ์ด ๋  ๋•Œ๋งˆ๋‹ค ์œ ํšจ์„ฑ์„ ๊ฒ€์ฆํ•˜์ง€ ์•Š์•˜๋‹ค๋Š” ์˜๋ฏธ์ด๋‹ค. ์ด๋ฏธ form ์„ ์ œ์ถœํ•˜๋ฉด์„œ ์œ ํšจ์„ฑ์„ ๊ฒ€์ฆํ•˜๋Š” ๋ฐฉ์‹ ๋งŒ์œผ๋กœ ๊ดœ์ฐฎ์„ ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฑธ ์•Œ์•˜๋‹ค. ํ•˜์ง€๋งŒ ์ด์ œ๋Š” ์กฐ๊ธˆ ๋” ๋‹ค์–‘ํ•œ ๊ด€์ ์—์„œ ๋˜ ๋‹ค๋ฅธ ๋ฐฉ์‹์œผ๋กœ ์œ ํšจ์„ฑ ๊ฒ€์ฆ์ด ์ž‘๋™ํ•ด์•ผ ํ•˜๋Š”์ง€์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณผ ํ•„์š”๊ฐ€ ์žˆ๋‹ค.
const [enteredName, setEnteredName] = useState("");
const [enteredNameIsValid, setEnteredNameIsValie] = useState(false);
const [enteredNameTouched, setEnteredNameTouched] = useState(false);
  • ์ง€๊ธˆ๊นŒ์ง€ ์„ธ ๊ฐ€์ง€์˜ ์ƒํƒœ(state) ๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ์œ ํšจ์„ฑ ๊ฒ€์ฆ์— ์‚ฌ์šฉํ–ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด๋Ÿฌํ•œ ์ž‘๋™ ๋ฐฉ์‹์ด ์•„์ง์€ ์‚ฌ์šฉ์ž ๊ฒฝํ—˜ ์ธก๋ฉด์—์„œ ํšจ์œจ์ ์ด๋ผ๊ณ  ํ•  ์ˆ˜๋Š” ์—†๋‹ค. form ์ด ์ œ์ถœ๋˜์—ˆ์„ ๋•Œ ์—๋Ÿฌ ๋ฉ”์„ธ์ง€๋ฅผ ๋„์šฐ๋Š” ๊ฒƒ์€ ๊ฝค ๊ดœ์ฐฎ์€ ๋ฐฉ๋ฒ•์ด์ง€๋งŒ, ๋งŒ์•ฝ ์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅ์ฐฝ์— ํด๋ฆญ๋งŒ ํ–ˆ๋‹ค๋ฉด ๊ทธ๋Ÿฌ๋‹ˆ๊นŒ ์ž…๋ ฅ์ฐฝ์„ ๊ฑด๋“œ๋ฆฌ๊ธฐ๋งŒ ํ–ˆ๋‹ค๋ฉด ์—๋Ÿฌ ๋ฉ”์„ธ์ง€๋Š” ๋œจ์ง€ ์•Š๋Š”๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋ฌด์–ธ๊ฐ€๋ฅผ ์ž…๋ ฅํ•˜๊ณ  ๋‹ค์‹œ ์ง€์šด ํ›„ ์ž…๋ ฅ์ฐฝ ๋ฐ”๊นฅ์„ ํด๋ฆญํ–ˆ์„ ๋•Œ ๋น„์–ด์žˆ๋Š” ์ž…๋ ฅ์€ ํ—ˆ์šฉ๋˜์ง€ ์•Š๊ธฐ์— ์œ ํšจํ•˜์ง€ ์•Š์€ ๊ฐ’์ด์ง€๋งŒ ์ด ์—ญ์‹œ ์—๋Ÿฌ ๋ฉ”์„ธ์ง€๋Š” ๋œจ์ง€ ์•Š๋Š”๋‹ค. ์˜ค๋กœ์ง€ ์‚ฌ์šฉ์ž๊ฐ€ form ์„ ์ œ์ถœํ•˜๋Š” ๋ฒ„ํŠผ์„ ๋ˆŒ๋ €์„ ๋•Œ์—๋งŒ ์ด๊ฒƒ์ด ์œ ํšจํ•œ ๊ฐ’์ธ์ง€์— ๋Œ€ํ•ด ์ฒดํฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜๊ณ , ์ด๋Š” ์‚ฌ์šฉ์ž์—๊ฒŒ ๋Š๋ฆฐ ํ”ผ๋“œ๋ฐฑ์„ ์ฃผ๋ฉฐ ์ตœ์ ์˜ ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ์ œ๊ณตํ•  ์ˆ˜ ์—†๋‹ค๋Š” ๋œป์ด ๋œ๋‹ค.

์ž…๋ ฅ ์ฐฝ์ด ํฌ์ปค์Šค ์•„์›ƒ ๋  ๋•Œ ์—๋Ÿฌ ๋ฉ”์„ธ์ง€๋ฅผ ๋„์šฐ๊ธฐ

  • ์—ฌ๊ธฐ์„œ ๋” ๋‚˜์€ ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ์ œ๊ณตํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅ ์ฐฝ์— ์–ด๋–ค ๊ฐ’์„ ์ž…๋ ฅํ•  ์ˆ˜ ์žˆ์„ ๋•Œ์— ์—๋Ÿฌ ๋ฉ”์„ธ์ง€๋ฅผ ๋ณด์—ฌ์ค€๋‹ค๋ฉด ๋” ๋น ๋ฅธ ํ”ผ๋“œ๋ฐฑ์„ ์ค„ ์ˆ˜ ์žˆ๋‹ค. ๋˜ ์ž…๋ ฅ ์ฐฝ์„ ๋นˆ์นธ์œผ๋กœ ๋‘” ์ฑ„๋กœ ๋ฐ”๊นฅ์„ ํด๋ฆญํ•œ๋‹ค๋ฉด ์ด๋Ÿฌํ•œ ๊ฐ’์€ ํ—ˆ์šฉ๋˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๋ฉ”์„ธ์ง€ ์—ญ์‹œ ๋„์šธ ์ˆ˜๋„ ์žˆ๋‹ค. ์™œ๋ƒํ•˜๋ฉด ์ด๋•Œ ์‚ฌ์šฉ์ž๋Š” ์ž…๋ ฅํ•  ์ˆ˜ ์žˆ์—ˆ์Œ์—๋„ ๊ทธ๋ ‡๊ฒŒ ํ•˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— ์ž…๋ ฅ ์นธ์— ๋ฌด์–ธ๊ฐ€๋ฅผ ๋ฐ˜๋“œ์‹œ ์ž…๋ ฅํ•ด์•ผ ํ•œ๋‹ค๊ณ  ํ”ผ๋“œ๋ฐฑ์„ ์ค˜์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ๋”ฐ๋ผ์„œ ์šฐ๋ฆฌ๋Š” ๋ธ”๋Ÿฌ๋ผ๋Š” ๊ฒƒ์ด ๋˜์—ˆ์„ ๋•Œ์—๋„ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๋ฅผ ํ•  ์ˆ˜ ์žˆ๋„๋ก ์ž‘์—…ํ•ด์ค„ ์š”๋Ÿ‰์ด๋‹ค.

onBlur ์‚ฌ์šฉํ•˜๊ธฐ

  • ๋ธ”๋Ÿฌ๋Š” input ์š”์†Œ๊ฐ€ ํฌ์ปค์Šค ์•„์›ƒ ๋˜์—ˆ๋‹ค๋Š” ์˜๋ฏธ๋กœ, ์‚ฌ์‹ค ๊ทธ๋ ‡๊ฒŒ ์–ด๋ ค์šด ๊ฐœ๋…์€ ์•„๋‹ˆ๋‹ค.
<input
  ref={nameInputRef}
  type="text"
  id="name"
  onChange={nameInputChangeHandler}
  onBlur={}
  value={enteredName}
/>
  • <input> ํƒœ๊ทธ ์†์„ฑ์— onBlur๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค. ์ด๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ด๋ฒคํŠธ ์†์„ฑ์œผ๋กœ input ์š”์†Œ๊ฐ€ ํฌ์ปค์Šค ์•„์›ƒ ๋˜๋Š” ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ์‹œ์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
const nameInputBlurHandler = (event) => {};
  • onBlur ์— ๋ฐ”์ธ๋”ฉํ•  ํ•จ์ˆ˜ nameInputBlurHandler๋ฅผ ์ž‘์„ฑํ•œ๋‹ค. ์ด์ œ ์ด ํ•จ์ˆ˜์—์„œ๋Š” ๋‘ ๊ฐ€์ง€๋ฅผ ํ•  ๊ฒƒ์ธ๋ฐ,
const nameInputBlurHandler = (event) => {
  setEnteredNameTouched(true);
};
  • ์ฒซ ๋ฒˆ์งธ๋กœ๋Š” setEnteredNameTouched๋ฅผ ์‚ฌ์šฉํ•ด์„œ true ๋กœ ์—…๋ฐ์ดํŠธ ํ•ด์ค„ ๊ฒƒ์ด๋‹ค. ์ž…๋ ฅ์ฐฝ์—์„œ ํฌ์ปค์Šค ์•„์›ƒ ๋˜์—ˆ๋‹ค๋Š” ์˜๋ฏธ๋Š” ์ง์ „์— ์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅ์ฐฝ์„ ๊ฑด๋“œ๋ ธ๊ธฐ ๋•Œ๋ฌธ์— ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ์ด๋ฒคํŠธ์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ์ฆ‰, ์ž…๋ ฅํ•  ๊ธฐํšŒ๊ฐ€ ์žˆ์—ˆ๋‹ค๋Š” ๋œป์ด๋‹ค.
const nameInputBlurHandler = (event) => {
  setEnteredNameTouched(true);

  if (enteredName.trim() === "") {
    setEnteredNameIsValie(false);
    return;
  }
};
  • ๋‘ ๋ฒˆ์งธ๋กœ ํ•ด์ค„ ์ผ์€ ํ•จ์ˆ˜ ๋‚ด๋ถ€์—์„œ ์œ ํšจ์„ฑ ๊ฒ€์ฆ์„ ํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ์ด๋ฅผ ์œ„ํ•ด์„œ ์•„๋ž˜์˜ formSubmitssionHandler์—์„œ ์ถ”๊ฐ€ํ•ด์ฃผ์—ˆ๋˜ ์œ ํšจ์„ฑ ๊ฒ€์ฆ ๋กœ์ง์„ ๊ธ์–ด์™€ ๊ทธ๋Œ€๋กœ ๋ถ™์—ฌ๋„ฃ๊ธฐ ํ•ด์ค€๋‹ค. ์ด ์—ญ์‹œ enteredName๊ฐ€ ๊ณต๋ฐฑ์ด ์—†๋Š” ์ƒํƒœ์—์„œ ๋นˆ ๋ฌธ์ž์—ด์ธ์ง€๋ฅผ ํ™•์ธํ•˜๊ณ , ์ด ๊ฐ’์ด ๋งŒ์•ฝ ๋นˆ ๋ฌธ์ž์—ด์ด๋ผ๋ฉด enteredNameIsValid๋ฅผ false ๋กœ ๋ฐ”๊ฟ”์ค€๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์ฝ”๋“œ๊ฐ€ ์ค‘๋ณต๋˜์ง€๋งŒ ์ดํ›„์— ๋ฆฌํŒฉํ† ๋ง์„ ํ•  ์˜ˆ์ •์ด๋‹ˆ ๋ฏธ๋ฆฌ ๊ฑฑ์ •ํ•˜์ง€ ๋ง์ž.

  • ์ž…๋ ฅ์ฐฝ์„ ํด๋ฆญํ•˜๊ณ  ๋‹ค์‹œ ์ž…๋ ฅ์ฐฝ ๋ฐ”๊นฅ์„ ํด๋ฆญํ•˜๋ฉด ๊ฒฝ๊ณ  ๋ฉ”์„ธ์ง€๊ฐ€ ์ถœ๋ ฅ๋˜๋Š” ๊ฑธ ์•Œ ์ˆ˜ ์žˆ๋‹ค. ์ด๋Š” ๊ฒฐ๊ณผ์ ์œผ๋กœ ์ด์ „๋ณด๋‹ค๋Š” ๋” ๋‚˜์€ ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ์ฃผ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ธ๋‹ค.

์ •๋ฆฌ

  • ์ด์ œ ์ด๋Ÿฌํ•œ ์˜ค๋ฅ˜๋ฅผ ๊ณ ์น  ๊ธฐํšŒ๋ฅผ ์‚ฌ์šฉ์ž์—๊ฒŒ ์ค˜์•ผํ•œ๋‹ค. ์—ฌ๊ธฐ์— ๋ฌด์–ธ๊ฐ€๋ฅผ ์ž…๋ ฅํ•˜๊ธฐ ์‹œ์ž‘ํ•˜๋Š” ์ˆœ๊ฐ„์— ์—๋Ÿฌ ๋ฉ”์„ธ์ง€๊ฐ€ ์‚ฌ๋ผ์ง„๋‹ค๋ฉด ์–ด๋–จ๊นŒ? ํ›จ์”ฌ ๋‚˜์€ ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ์ด๋‹ค. ์ด๋ ‡๊ฒŒ ํ”ผ๋“œ๋ฐฑ์„ ์‹ค์‹œ๊ฐ„์œผ๋กœ ์ „๋‹ฌํ•œ๋‹ค๋ฉด ์‚ฌ์šฉ์ž๊ฐ€ ์œ ํšจํ•˜์ง€ ์•Š์€ ๊ฐ’์„ ์ž…๋ ฅํ–ˆ์„ ๋•Œ ์ด๋ฅผ ์ฆ‰์‹œ ์ธ์ง€ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๊ณ  ์ž˜๋ชป๋œ ์ž…๋ ฅ์„ ๋ฉˆ์ถœ ์ˆ˜ ์žˆ๋‹ค. ์ด์™€ ๊ฐ™์€ ๊ฒฝ์šฐ์—๋Š” ํ‚ค ์ž…๋ ฅ๋งˆ๋‹ค ์œ ํšจ์„ฑ์„ ๊ฒ€์ฆํ•˜๋Š” ๋ฐฉ์‹์ด ์ข‹์„ ๊ฒƒ์ด๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ด๋Š” ์ด์ „์— ์šฐ๋ฆฌ๊ฐ€ ์ถ”๊ฐ€ํ•œ ๋‹ค๋ฅธ ๊ฒ€์ฆ ์ ˆ์ฐจ์™€ ์กฐํ•ฉํ•ด์„œ ์‚ฌ์šฉ๋˜์–ด์•ผ ํ•  ๊ฒƒ์ด๋‹ค. ์™œ๋ƒํ•˜๋ฉด ํ‚ค ์ž…๋ ฅ๋งˆ๋‹ค ์œ ํšจ์„ฑ์„ ๊ฒ€์ฆํ•˜๋Š” ๋ฐฉ์‹๋งŒ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด, ์‚ฌ์šฉ์ž๊ฐ€ ์œ ํšจํ•œ ๊ฐ’์„ ์ž…๋ ฅํ•  ๊ธฐํšŒ์กฐ์ฐจ ์ฃผ์ง€ ์•Š๊ณ  ์—๋Ÿฌ๋ฅผ ์ถœ๋ ฅํ• ์ง€๋„ ๋ชจ๋ฅด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ๋ฐ˜๋ฉด ์šฐ๋ฆฌ๊ฐ€ ์•ž์„œ ์‚ฌ์šฉํ•œ ๋ฐฉ์‹๋“ค์„ ์กฐํ•ฉํ•˜๊ฒŒ ๋˜๋ฉด ์ž…๋ ฅ ์ฐฝ์ด ํฌ์ปค์Šค ์•„์›ƒ๋˜๊ฑฐ๋‚˜ ํผ์ด ์ œ์ถœ๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•ด์„œ ์‚ฌ์šฉ์ž๊ฐ€ ์œ ํšจํ•œ ๊ฐ’์„ ์ œ์ถœํ•  ๊ธฐํšŒ๋ฅผ ์ค„ ์ˆ˜ ์žˆ๊ฒŒ ๋  ๊ฒƒ์ด๋‹ค.

โœง ๋ฆฌํŒฉํ† ๋ง ๋ฐ State ํŒŒ์ƒ

  • ์ด๋ฒˆ์—๋Š” ํ‚ค๋ฅผ ์ž…๋ ฅํ•  ๋•Œ๋งˆ๋‹ค ์œ ํšจ์„ฑ์„ ๊ฒ€์ฆํ•ด๋ณผ ๊ฒƒ์ด๋‹ค.
const nameInputChangeHandler = (event) => {
  setEnteredName(event.target.value);
};
  • input์˜ ์ž…๋ ฅ ๊ฐ’์„ ์‹ค์‹œ๊ฐ„์œผ๋กœ ๋ฐ›์•„์˜ค๋Š” nameInputChangeHandler ํ•จ์ˆ˜์— ์šฐ๋ฆฌ๊ฐ€ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๋ฅผ ํ–ˆ๋˜ ๋กœ์ง์„ ๊ทธ๋Œ€๋กœ ๋ณต์‚ฌํ•ด์„œ ๊ฐ€์ ธ์˜จ๋‹ค.
const nameInputChangeHandler = (event) => {
  setEnteredName(event.target.value);

  if (enteredName.trim() === "") {
    setEnteredNameIsValie(false);
    return;
  }
};
  • ์‚ฌ์‹ค ์ด ๋ฐฉ๋ฒ•์€ ๋ถ€์ •ํ™•ํ•œ ๋ฐฉ๋ฒ•์ด๋‹ค. ์ด ๋ฐฉ๋ฒ•์€ ๊ฐ’์ด ์œ ํšจํ•˜์ง€ ์•Š์€์ง€๋ฅผ ํ™•์ธํ•ด์„œ ๊ทธ๋•Œ setEnteredNameIsValie์„ false ๋กœ ์—…๋ฐ์ดํŠธํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ํ•˜์ง€๋งŒ ํ‚ค๋ฅผ ์ž…๋ ฅํ•  ๋•Œ๋งˆ๋‹ค ๊ฐ’์ด ์œ ํšจํ•œ์ง€๋ฅผ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์ตœ๋Œ€ํ•œ ๋น ๋ฅด๊ฒŒ ์œ ํšจํ•˜์ง€ ์•Š์•˜์„ ๋•Œ ์ถœ๋ ฅ๋˜๋Š” ์—๋Ÿฌ๋ฅผ ์ œ๊ฑฐํ•ด์•ผ ํ•œ๋‹ค. ๋”ฐ๋ผ์„œ ์—ฌ๊ธฐ์—์„œ๋Š” ์•ฝ๊ฐ„์˜ ๋กœ์ง์„ ์ˆ˜์ •ํ•ด์•ผ ํ•  ํ•„์š”๊ฐ€ ์žˆ๋‹ค.
const nameInputChangeHandler = (event) => {
  setEnteredName(event.target.value);

  if (enteredName.trim() !== "") {
    setEnteredNameIsValie(true);
  }
};
  • ์ด ๋กœ์ง์—์„œ๋Š” ===๋ฅผ !==๋กœ ๋ฐ”๊พธ๊ณ , enteredName.trim()์ด ๋นˆ ๊ฐ’์ด ์•„๋‹ ๋•Œ์— setEnteredNameIsValie์ด true ๊ฐ€ ๋  ์ˆ˜ ์žˆ๋„๋ก ์ˆ˜์ •ํ•ด์ฃผ์—ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ๋˜๋ฉด ์กฐ๊ฑด๋ฌธ ๋’ค์— ์‹คํ–‰ํ•  ์ฝ”๋“œ๊ฐ€ ์—†๊ธฐ์— return ์€ ํ•„์š” ์—†์–ด์ง€๋ฏ€๋กœ ์ œ๊ฑฐ ํ•œ๋‹ค.
const nameInputBlurHandler = (event) => {
  setEnteredNameTouched(true);

  if (enteredName.trim() === "") {
    setEnteredNameIsValie(false);
  }
};
  • ์œ„์˜ ์‚ฌ๋ก€์™€ ๋™์ผํ•˜๊ธฐ์— nameInputBlurHandler ํ•จ์ˆ˜ ๋‚ด๋ถ€์˜ ๋กœ์ง๋„ return ์„ ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.
const nameInputChangeHandler = (event) => {
  setEnteredName(event.target.value);

  if (enteredName.trim() !== "") {
    setEnteredNameIsValie(true);
  }
};
  • ์ด์ œ, nameInputChangeHandler ํ•จ์ˆ˜์—์„œ ์ž…๋ ฅ ๊ฐ’์„ ๊ฒ€์ฆํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค. ์—ฌ๊ธฐ์—์„œ ์ฐธ๊ณ ํ•  ์ ์€ ์šฐ๋ฆฌ๊ฐ€ ํผ์„ ์ œ์ถœํ•  ๋•Œ ์‚ฌ์šฉํ–ˆ๋˜ ๊ฒƒ์ฒ˜๋Ÿผ enteredName ์ƒํƒœ(state)๊ฐ’์„ ์ด์šฉํ•ด์„œ ์œ ํšจ์„ฑ์„ ๊ฒ€์ฆํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ, event.target.value๋ฅผ ์ด์šฉํ•ด์•ผ ํ•œ๋‹ค๋Š” ์ ์ด๋‹ค.
const nameInputChangeHandler = (event) => {
  setEnteredName(event.target.value);

  if (event.target.value.trim() !== "") {
    setEnteredNameIsValie(true);
  }
};
  • ์™œ๋ƒํ•˜๋ฉด nameInputChangeHandler ํ•จ์ˆ˜์—์„œ setEnteredName๋ฅผ ํ†ตํ•ด์„œ ์—…๋ฐ์ดํŠธํ•ด์ฃผ๊ณ  ์žˆ๊ธด ํ•˜์ง€๋งŒ ์ด์ „์— ๋ฐฐ์› ๋˜ ๊ฒƒ์ฒ˜๋Ÿผ ์ด๋Ÿฌํ•œ ์ƒํƒœ(state)๋“ค์€ ๋ฆฌ์•กํŠธ์—์„œ ๋น„๋™๊ธฐ์ ์œผ๋กœ ์ฒ˜๋ฆฌ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์ฆ‰๊ฐ์ ์œผ๋กœ ๋ฐ˜์˜๋˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. setEnteredName ์—์„œ event.target.value๋ฅผ ํ†ตํ•ด์„œ enteredName์„ ์—…๋ฐ์ดํŠธํ•˜๊ณ  ์žˆ์ง€๋งŒ ๋‹ค์Œ ์ค„์ด ์‹คํ–‰๋  ๋•Œ์— ์ด enteredName๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ์ตœ์‹ ์˜ ์ƒํƒœ(state)๋ฅผ ๋ฐ˜์˜ํ•˜์ง€ ๋ชปํ•˜๊ณ , ์ด์ „์˜ ์ƒํƒœ(state)๋ฅผ ์ฐธ๊ณ ํ•˜๊ฒŒ ๋œ๋‹ค. ๋”ฐ๋ผ์„œ nameInputChangeHandler ํ•จ์ˆ˜ ๋‚ด๋ถ€์—์„œ ์ƒํƒœ๋ฅผ ์—…๋ฐ์ดํŠธ ํ•˜๋Š”๋ฐ์— ์‚ฌ์šฉ๋œ event.target.value๋ฅผ ์‚ฌ์šฉํ•ด์•ผ๋งŒ ํ•œ๋‹ค.

์ฝ”๋“œ์˜ ๋ฌธ์ œ์ 

  • ์ด์ œ ํฌ์ปค์Šค๋ฅผ ์žƒ๋Š” ์ˆœ๊ฐ„์ด๋‚˜ ํผ์„ ์ œ์ถœํ•˜๋Š” ์ˆœ๊ฐ„ ๊ฐ’์˜ ์œ ํšจ์„ฑ์„ ๊ฒ€์ฆํ•˜์—ฌ ์œ ํšจํ•˜์ง€ ์•Š๋‹ค๋ฉด ์—๋Ÿฌ ๋ฉ”์„ธ์ง€๋ฅผ ๋„์šฐ๋ฉฐ, ์‚ฌ์šฉ์ž๋Š” ์ฆ‰๊ฐ์ ์ธ ํ”ผ๋“œ๋ฐฑ์„ ์–ป๊ฒŒ ๋˜๊ณ  ๋™์‹œ์— ํ‚ค ์ž…๋ ฅ์— ๋”ฐ๋ผ ์—๋Ÿฌ๋ฅผ ๊ณ ์น  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ๋‹ค. ์‚ฌ์šฉ์ž ๊ฒฝํ—˜ ์ธก๋ฉด์—์„œ ๋ถ„๋ช…ํžˆ ๋งŽ์€ ๊ฒƒ๋“ค์ด ์ข‹์•„์กŒ์ง€๋งŒ input ์š”์†Œ ํ•˜๋‚˜์— ์—„์ฒญ๋‚˜๊ฒŒ ๋งŽ์€ ์ฝ”๋“œ๋“ค์ด ์ค‘๋ณต๋˜์–ด ์‚ฌ์šฉ๋˜๊ณ  ์žˆ๋‹ค๋Š” ์ ์—์„œ ๋ถ„๋ช… ์ข‹์€ ์ฝ”๋“œ๋ผ๊ณ  ๋งํ•˜๊ธฐ๋Š” ์–ด๋ ค์šธ ๊ฒƒ์ด๋‹ค.

์ค‘๋ณต๋œ ์ฝ”๋“œ๋ฅผ ์ •๋ฆฌํ•˜๊ธฐ

  • ํ•ด๋‹น ์ฝ”๋“œ์˜ ๋ฌธ์ œ์ ์€ ๋ฌด์—‡์ผ๊นŒ? ๋จผ์ € ๋ฐ˜๋ณต๋˜๋Š” ์ฝ”๋“œ ๋กœ์ง์ด ๋งŽ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. ์œ ํšจ์„ฑ ๊ฒ€์ฆ์— ๋”ฐ๋ฅธ ์ฝ”๋“œ๋งŒ์œผ๋กœ๋„ ์ด๋ฏธ ๋งŽ์€ ์ค„์„ ์ฐจ์ง€ํ•˜๊ฒŒ ๋˜์—ˆ๋Š”๋ฐ, ๋ณดํ†ต์˜ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์ด๋ผ๋ฉด ์ด๋ณด๋‹ค ๋” ๋งŽ์€ ๋กœ์ง๋“ค์ด ์ถ”๊ฐ€๋  ๊ฒƒ์ด๋‹ˆ ํ™•์‹คํžˆ ์ง€๊ธˆ๊นŒ์ง€๋Š” ์ข‹์€ ์ฝ”๋“œ๋ผ ๋งํ•˜๊ธด ํž˜๋“ค ๊ฒƒ์ด๋‹ค. ๊ทธ๋Ÿฌ๋‹ˆ ์ค‘๋ณต๋œ ์ฝ”๋“œ๋ฅผ ์ œ๊ฑฐํ•˜๊ณ  ๋ถˆํ•„์š”ํ•˜๊ฒŒ ๊ธธ์–ด์ง„ ์ฝ”๋“œ๋“ค์„ ์ •๋ฆฌํ•  ํ•„์š”๊ฐ€ ์žˆ๋‹ค. ์ตœ์ข…์ ์œผ๋กœ ์šฐ๋ฆฌ๊ฐ€ ํ•ด์•ผํ•˜๋Š” ๊ฒƒ์€ ์ž…๋ ฅ ๊ฐ’์ด ์œ ํšจํ•œ์ง€๋ฅผ ํ™•์ธํ•˜๊ณ  ์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅ์ฐฝ์„ ๊ฑด๋“œ๋ ธ๋Š”์ง€ ๋˜ํ•œ ํ™•์ธํ•˜๋ฉฐ ๊ฐ’์ด ์œ ํšจํ•˜์ง€ ์•Š์€ ์ƒํƒœ๋กœ ์ž…๋ ฅ์ฐฝ์„ ๊ฑด๋“œ๋ ธ์„ ๋•Œ ์‚ฌ์šฉ์ž์—๊ฒŒ ์—๋Ÿฌ๋ฅผ ๋ณด์—ฌ์ฃผ๊ฑฐ๋‚˜ ๋ณด์—ฌ์ฃผ์ง€ ์•Š๋Š” ๋“ฑ์˜ ์ผ์ผ ๊ฒƒ์ด๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ด๋Ÿฌํ•œ ๋ชฉํ‘œ๋ฅผ ์œ„ํ•ด์„œ ์šฐ๋ฆฌ๋Š” ๊ตณ์ด enteredNameIsValid๋ฅผ ์‚ฌ์šฉํ•  ํ•„์š˜ ์—†๋‹ค.
const [enteredName, setEnteredName] = useState("");
const [enteredNameIsValid, setEnteredNameIsValie] = useState(false);
const [enteredNameTouched, setEnteredNameTouched] = useState(false);
  • ๋จผ์ € ์ด์ œ๋Š” ํ•„์š”ํ•˜์ง€ ์•Š์€ useEffect ํ•จ์ˆ˜๋ถ€ํ„ฐ ์ง€์›Œ์ฃผ์ž.
// useEffect(() => {
//   if (enteredNameIsValid) {
//     // true ์ผ ๋•Œ
//     console.log("Name Input Is valid!"); // ์ฝ˜์†”์— ์ถœ๋ ฅํ•œ๋‹ค
//   }
// }, [enteredNameIsValid]);
  • ๋Œ€์‹  enteredNameIsValid ์ƒํƒœ๋ฅผ ์ œ๊ฑฐํ•˜๊ณ , ๋™์ผํ•œ ์ด๋ฆ„์˜ ์ƒ์ˆ˜๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค.
const [enteredName, setEnteredName] = useState("");
const [enteredNameTouched, setEnteredNameTouched] = useState(false);

const enteredNameIsValid;
  • ์ด์ œ ์šฐ๋ฆฌ๋Š” enteredName์™€ enteredNameTouched ์ƒํƒœ๋งŒ ์‚ฌ์šฉํ•œ๋‹ค. ์™œ๋ƒํ•˜๋ฉด enteredNameIsValid ๋Š” ์–ด์จŒ๋“  enteredName ๋ผ๋Š” ์ƒํƒœ๋กœ๋ถ€ํ„ฐ ์–ป์–ด๋‚ผ ์ˆ˜ ์žˆ๋Š” ๊ฐ’์ด๊ธฐ ๋•Œ๋ฌธ์ด๋ฉฐ, ์ƒˆ๋กœ์šด ๊ฐ’์ด ์ž…๋ ฅ๋  ๋•Œ๋งˆ๋‹ค ์ด ์ „์ฒด ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋‹ค์‹œ ์‹คํ–‰๋˜๊ธฐ ๋•Œ๋ฌธ์— enteredNameIsValid์˜ ๊ฐ’์€ ๊ฐ€์žฅ ์ตœ์‹ ์˜ enteredName์™€ ๊ฐ€์žฅ ์ตœ์‹ ์˜ setEnteredNameTouched ์ƒํƒœ๋ฅผ ๋ฐ˜์˜ํ•˜๊ฒŒ ๋˜๊ธฐ ๋–„๋ฌธ์ด๋‹ค. ์–ด์จŒ๋“  ์ด ๋‘ ์ƒํƒœ ์ค‘ ํ•˜๋‚˜๋ผ๋„ ์—…๋ฐ์ดํŠธ ๋œ๋‹ค๋ฉด, ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๋Š” ๋ฆฌ๋ Œ๋”๋ง ๋  ๊ฒƒ์ด๋‹ค.
const [enteredName, setEnteredName] = useState("");
const [enteredNameTouched, setEnteredNameTouched] = useState(false);

const enteredNameIsValid = enteredName.trim() !== "";
  • ์ƒ์ˆ˜ enteredNameIsValid์˜ ๊ฐ’์—๋Š” enteredName ์ƒํƒœ ๊ฐ’์— ๊ณต๋ฐฑ์„ ์ œ๊ฑฐํ•œ ๊ฐ’์ด ๋นˆ ๋ฌธ์ž์—ด์ด ์•„๋‹ ๋•Œ true ์ผ ์ˆ˜ ์žˆ๊ฒŒ๋” ์ž‘์„ฑํ•ด์ค€๋‹ค. enteredNameIsValid์˜ ์กฐ๊ฑด์‹ ๊ฐ’์ด true ๋ผ๋ฉด enteredNameIsValid๋„ true์ธ ์…ˆ์ด๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ด์ œ ๋”์ด์ƒ enteredNameIsValid๋ฅผ ์ƒํƒœ๋กœ ๊ด€๋ฆฌํ•ด์ฃผ์ง€ ์•Š๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— setEnteredNameIsValid๊ฐ€ ์‚ฌ์šฉ๋œ ๋ชจ๋“  ์ฝ”๋“œ๋ฅผ ์ง€์šธ ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.
const enteredNameIsValid = enteredName.trim() !== "";

const nameInputChangeHandler = (event) => {
  setEnteredName(event.target.value);
};
  • ์™œ๋ƒํ•˜๋ฉด ์ด ๊ฐ’์„ ์ด๋ฏธ ์กด์žฌํ•˜๋Š” ์ƒํƒœ(state)๋กœ ๋ถ€ํ„ฐ ์–ป์–ด๋‚ด๊ธฐ์— ์ถฉ๋ถ„ํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
const nameInputChangeHandler = (event) => {
  setEnteredName(event.target.value);

  if (event.target.value.trim() !== "") {
    setEnteredNameIsValie(true);
  }
};
  • nameInputBlurHandler ํ•จ์ˆ˜๋Š” ์–ด๋–จ๊นŒ? ์—ฌ๊ธฐ์—์„œ๋„ ๊ฒฐ๊ตญ์—” ์œ ํšจ์„ฑ ๊ฒ€์ฆ์ด ํ•„์š” ์—†์œผ๋‹ˆ, ์ด ๋ถ€๋ถ„์„ ์‚ญ์ œํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.
const enteredNameIsValid = enteredName.trim() !== "";
const nameInputIsInvalid = !enteredNameIsValid && enteredNameTouched;

const nameInputBlurHandler = (event) => {
  setEnteredNameTouched(true);
};
  • ๋Œ€์‹  enteredName ์ƒํƒœ(state)๋ฅผ ํ†ตํ•ด์„œ ์–ป์€ enteredNameIsValid๊ณผ ๋…ผ๋ฆฌ์—ฐ์‚ฐ์„ ํ†ตํ•ด ์–ป์€ nameInputIsInvalid๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
const [enteredName, setEnteredName] = useState("");
const [enteredNameTouched, setEnteredNameTouched] = useState(false);

const enteredNameIsValid = enteredName.trim() !== "";
const nameInputIsInvalid = !enteredNameIsValid && enteredNameTouched;
  • ์ด๋ ‡๊ฒŒ ์•„๋ž˜ ๋‘ ์ค„์€ ํ•จ๊ป˜ ์ž‘๋™ํ•œ๋‹ค. ๋จผ์ € enteredName์ด ์œ ํšจํ•œ์ง€๋ฅผ ํ™•์ธํ•˜๊ณ (enteredNameIsValid) ์œ ํšจํ•˜์ง€ ์•Š๋‹ค๋ฉด, enteredNameTouched์™€ ์กฐํ•ฉ(nameInputIsInvalid) ํ•œ๋‹ค.
const formSubmitssionHandler = (event) => {
  event.preventDefault();
  setEnteredNameTouched(true);

  if (enteredName.trim() === "") {
    setEnteredNameIsValie(false);
    return;
  }

  setEnteredNameIsValie(true);
  setEnteredName("");
};
  • ์ด์ œ enteredNameIsValid๋ผ๋Š” ์ƒํƒœ(state)๋Š” ์‚ฌ๋ผ์กŒ๋‹ค. ํผ์„ ์ œ์ถœํ•˜๋Š” ํ•จ์ˆ˜์ธ formSubmitssionHandler ์—ญ์‹œ ์ˆ˜์ •ํ•  ํ•„์š”๊ฐ€ ์žˆ์„ ๊ฒƒ์ด๋‹ค. ํ•˜์ง€๋งŒ ์ž…๋ ฅ ๊ฐ’์ด ์œ ํšจํ•˜์ง€ ์•Š์„ ๋•Œ ํ•ด๋‹น ํ•จ์ˆ˜๋ฅผ ์ค‘๋‹จํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์กฐ๊ฑด๋ฌธ์€ ์œ ์ง€ํ•ด์•ผ ํ•œ๋‹ค. ๊ทธ๋ ‡๊ธฐ์— ์œ ํšจ์„ฑ์„ ๋ฐ”๊ฟ”์ฃผ๋Š” ๋Œ€์‹ ์— ์‚ฌ๋ผ์ง„ ์ƒํƒœ ์—…๋ฐ์ดํŠธ ๊ฐ’์ธ setEnteredNameIsValie๋ฅผ ์‚ฌ์šฉํ•œ ๋กœ์ง์€ ๋ชจ๋‘ ์ง€์›Œ์ฃผ๊ณ , ์กฐ๊ฑด์‹์— enteredNameIsValid๊ฐ€ false ์ธ์ง€๋งŒ ํ™•์ธํ•˜๋ฉด ๋œ๋‹ค.
const formSubmitssionHandler = (event) => {
  event.preventDefault();
  setEnteredNameTouched(true);

  if (!enteredNameIsValid) {
    return;
  }

  setEnteredName("");
};
  • ์ด์ œ enteredNameIsValid๊ฐ€ false ๋ผ๋ฉด, ํ•ด๋‹น ํ•จ์ˆ˜๊ฐ€ ์ค‘๋‹จ๋  ์ˆ˜ ์žˆ๋„๋ก return ํ•ด์ฃผ์—ˆ๋‹ค. formSubmitssionHandler ํ•จ์ˆ˜๋Š” ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ฆฌ๋ Œ๋”๋ง ๋  ๋•Œ๋งˆ๋‹ค ๋‹ค์‹œ ์ƒ์„ฑ๋˜๋ฉฐ, ๋”ฐ๋ผ์„œ formSubmitssionHandler์€ ๋งค๋ฒˆ enteredNameIsValid์˜ ์ตœ์‹  ๊ฐ’์„ ๊ฐ€์ ธ์˜ค๊ฒŒ ๋œ๋‹ค.

  • ์ €์žฅํ•˜๊ณ , ์ƒˆ๋กœ๊ณ ์นจ ํ•œ ๋’ค์— ๊ฐ’์„ ์ ์–ด Submit ๋ฒ„ํŠผ์œผ๋กœ ํผ์„ ์ œ์ถœํ•˜๊ณ  ๋‚˜๋ฉด ์ œ๋Œ€๋กœ ๋œ ๊ฐ’์„ ์ œ์ถœํ–ˆ์Œ์—๋„ ์—๋Ÿฌ ๋ฉ”์„ธ์ง€๊ฐ€ ๋œจ๋Š” ๊ฑธ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋Š” ๋ฒ„๊ทธ๊ฐ€ ์•„๋‹ˆ๋ผ, ์šฐ๋ฆฌ๊ฐ€ ์ž‘์„ฑํ•œ ์ฝ”๋“œ์˜ ๊ฒฐ๊ณผ์ผ ๋ฟ์ด๋‹ˆ ์ˆ˜์ •์ด ํ•„์š”ํ•˜๋‹ค.
const formSubmitssionHandler = (event) => {
  event.preventDefault();
  setEnteredNameTouched(true);

  if (!enteredNameIsValid) {
    return;
  }

  setEnteredName("");
};
  • ํผ์„ ์ œ์ถœํ•˜๋Š” formSubmitssionHandler ํ•จ์ˆ˜๋ฅผ ๋ณด๋ฉด, ์œ ํšจ์„ฑ ๊ฒ€์ฆ์ด ๋๋‚œ ํ›„๋กœ ๊ทธ๋Ÿฌ๋‹ˆ๊นŒ ์œ ํšจ์„ฑ ๊ฒ€์ฆ์—์„œ true๊ฐ€ ๋˜์—ˆ์„ ๋•Œ ๊ฐ’์€ ์ œ์ถœ๋˜๋ฉด์„œ setEnteredName ๋ฅผ ํ†ตํ•ด ๋นˆ ๊ฐ’์œผ๋กœ ์ดˆ๊ธฐํ™” ํ•ด์ฃผ์—ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‹ˆ๊นŒ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ์—์„œ ๋นˆ ๊ฐ’์ผ ๋•Œ ์—๋Ÿฌ ๋ฉ”์„ธ์ง€๊ฐ€ ์ถœ๋ ฅ๋˜๋„๋ก ์šฐ๋ฆฌ๊ฐ€ ์ง€์ •ํ•ด๋†“์•˜๊ธฐ์— ๋ฐœ์ƒํ•œ ๋ฌธ์ œ์ด๋‹ค.
const formSubmitssionHandler = (event) => {
  event.preventDefault();
  setEnteredNameTouched(true);

  if (!enteredNameIsValid) {
    return;
  }

  setEnteredName("");
  setEnteredNameTouched(false);
};
  • ์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ํผ์ด ์ œ์ถœ๋˜๊ณ  ๋‚œ ํ›„๋กœ setEnteredNameTouched ๋ฅผ ํ†ตํ•ด์„œ ๊ฐ’์„ false ๋กœ ์ดˆ๊ธฐํ™”ํ•ด์ฃผ๋ฉด ๋œ๋‹ค. setEnteredName์„ ํ†ตํ•ด ํผ์ด ์ œ์ถœ๋˜๊ณ  ๋นˆ ๋ฌธ์ž์—ด์ด ๋งŒ๋“ค์–ด์ง€๋ฉด, ๊ทธ ๋‹ค์Œ์— ๋ฐ”๋กœ setEnteredNameTouched๋กœ ์ดˆ๊ธฐํ™”๋ฅผ ํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ํผ์ด ์ œ์ถœ๋˜๊ณ  ๋‚œ ๋’ค์—๋Š” ์ƒˆ๋กœ์šด ํผ์œผ๋กœ ๋Œ์•„๊ฐ€์„œ ์‚ฌ์šฉ์ž๊ฐ€ ๊ฑด๋“œ๋ฆฌ์ง€ ์•Š์€ ๊ฐ€์žฅ ์ตœ์ดˆ์˜ ์ƒํƒœ์™€ ๊ฐ™์ด ์ž‘๋™ํ•ด์•ผ๋งŒ ํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

  • ์ €์žฅ ํ›„ ์ƒˆ๋กœ๊ณ ์นจํ•ด๋ณด๋ฉด ํผ์„ ์ œ์ถœํ•ด๋„ ๋”์ด์ƒ ์—๋Ÿฌ ๋ฉ”์„ธ์ง€๊ฐ€ ๋œจ์ง€ ์•Š๋Š” ๊ฑธ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

์ •๋ฆฌ

  • ์ง€๊ธˆ๊นŒ์ง€ ์ž‘์„ฑํ•œ ์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด ํ™•์‹คํžˆ ์ด์ „๋ณด๋‹ค ์ฝ”๋“œ๊ฐ€ ๊ฐ„๋‹จํ•ด์ ธ์„œ ํ›จ์”ฌ ๋” ์ฝ๊ธฐ ์‰ฝ๊ณ  ๊ด€๋ฆฌํ•˜๊ธฐ ์‰ฌ์šด ์ฝ”๋“œ๊ฐ€ ๋œ ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค. ์—ฌ๋Ÿฌ ์ƒํƒœ(state)๋ฅผ ์ด์šฉํ•˜๋Š” ๊ฒƒ์„ ๋‘ ๊ฐœ์˜ ์ƒํƒœ๋กœ ์ค„์ด๊ณ , ๋ฐ˜๋ณต๋˜๋Š” ๋กœ์ง ์—ญ์‹œ ๋…ผ๋ฆฌ ์—ฐ์‚ฐ์ž๋ฅผ ํ†ตํ•ด ์ž‘์„ฑํ•œ ์ƒ์ˆ˜๋ฅผ ์ด์šฉํ•ด์„œ ์œ ํšจ์„ฑ์„ ๋„์ถœํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ๋‹ค.

โœฆ ์ถœ์ฒ˜


๐Ÿšจ ํ•ด๋‹น ํฌ์ŠคํŒ…์€ Udemy์˜ โŒœReact ์™„๋ฒฝ ๊ฐ€์ด๋“œโŒŸ ๊ฐ•์˜๋ฅผ ๋ฒ ์ด์Šค๋กœ ํ•œ ๊ธฐ๋ก์ž…๋‹ˆ๋‹ค.
โœ๐Ÿป ๊ฐ•์˜ git repo ๋ฐ”๋กœ๊ฐ€๊ธฐ

profile
์ผ๋‹จ ๊ณต๋ถ€๊ฐ€ '์ ์„ฑ'์— ๋งž๋Š” ๊ฐœ๋ฐœ์ž. ๊ทผ์„ฑ์žˆ์Šต๋‹ˆ๋‹ค.

0๊ฐœ์˜ ๋Œ“๊ธ€