React State์˜ ๋ชจ๋“  ๊ฒƒ ๐Ÿ˜Ž (feat. useState, useReducer, useRef, Custom Hooks)

osohyun0224ยท2024๋…„ 4์›” 27์ผ
0
post-thumbnail

์•ˆ๋…•ํ•˜์„ธ์š” ;) ์›น ํ”„๋ก ํŠธ์—”๋“œ ๊ฐœ๋ฐœ์ž Garden์ž…๋‹ˆ๋‹ค.

์ธํ„ด์„ ์‹œ์ž‘ํ•œ์ง€๋„ ์–ด๋Š ๋ง 4๊ฐœ์›”์ด ๋˜์–ด๊ฐ€๋Š” ์‹œ์ ์—์„œ ์ง€๋‚œ 4์›” ํ•œ ๋‹ฌ์€ ํ…Œ์ŠคํŠธ ์—…๋ฌด์—์„œ ๋ฒ—์–ด๋‚˜ ์ฒ˜์Œ์œผ๋กœ ์‚ฌ๋‚ด ์šด์˜์„ฑ ์—…๋ฌด ๋ฅผ ํ•˜๊ฒŒ ๋˜์—ˆ๋Š”๋ฐ์š”! ์ด๋•Œ ์‚ฌ๋‚ด ํ”„๋ก ํŠธ์—”๋“œ ์ฝ”๋“œ๋ฅผ ๊ฐ์žก๊ณ  ๊ผผ๊ผผํ•˜๊ฒŒ ๋ณด๊ฒŒ ๋˜์—ˆ๋Š”๋ฐ ์ด๋ฒˆ ์šด์˜์„ฑ ์—…๋ฌด๋“ค์„ ํ•˜๋ฉด์„œ ์•„๋ž˜์™€ ๊ฐ™์€ ์ด์œ  ๋•Œ๋ฌธ์— ๋ฐ˜์„ฑ์„ ๋งŽ์ด ํ•˜๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค ๐Ÿฅฒ

์™œ๋ƒํ•˜๋ฉด ์ œ๊ฐ€ ๊ทธ๋™์•ˆ ์ปดํฌ๋„ŒํŠธ ์ƒํƒœ๋Š” ๊ฑฐ์˜ ๋Œ€๋ถ€๋ถ„ useState๋กœ๋งŒ ๊ตฌํ˜„ํ–ˆ์—ˆ๋‹ค๋Š” ์ ์ด์—ˆ์Šต๋‹ˆ๋‹ค.. ์šฐ์„  "์ƒํƒœ๋ถ€ํ„ฐ ๊ตฌํ˜„ํ•˜๊ณ  ๋ณด์ž!" ๋ผ๋Š” ์ƒ๊ฐ์ด ์ญ‰ ์Šต๊ด€์œผ๋กœ ์ด์–ด์ ธ ๋œ ๊ฒƒ ๊ฐ™์•˜์–ด์š” .. ๊ทธ๋ž˜์„œ useReducer, useRef๋กœ ๊ด€๋ฆฌ๋˜๋Š” ์‚ฌ๋‚ด ์ฝ”๋“œ๋ฅผ ๋ณด์•˜์„ ๋•Œ ๋™์ž‘ ์›๋ฆฌ๋ฅผ ์ดํ•ดํ•˜๊ณ  ์ด๋ฅผ ์‘์šฉํ•ด์„œ useState -> useReducer, useRef๋กœ ๋ฆฌํŒฉํ† ๋งํ•˜๋Š” ๊ณผ์ •์—์„œ ์‹œ๊ฐ„์„ ๋งŽ์ด ํˆฌ์žํ–ˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

์œ„์˜ ์ด์Šˆ๋กœ ์ œ ์ง€๋‚œ ์‹œ๊ฐ„์„ ๋ฐ˜์„ฑํ•˜๋ฉฐ ์˜ค๋Š˜์€ React์—์„œ ์ƒํƒœ์— ๋Œ€ํ•œ ๋ชจ๋“  Hooks์— ๋Œ€ํ•ด ๋‹ค์‹œ ๊ณต๋ถ€ํ•˜๊ณ  ์Šค์Šค๋กœ ๋ˆ„๊ตฐ๊ฐ€์—๊ฒŒ ์„ค๋ช…ํ•˜๋“ฏ ์ •๋ฆฌํ•˜๋Š” ์‹œ๊ฐ„์„ ๊ฐ€์ ธ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค!

Intro.

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

๊ฒฐ๋ก ์ ์œผ๋กœ ์ƒํƒœ๋ฅผ ๊ด€๋ฆฌํ•˜๋ฉด์„œ ์ด๋•Œ ์ƒ๊ธฐ๋Š” ๋ Œ๋”๋ง ๋•Œ๋ฌธ์— ๊ณ„์† ์ตœ์ ํ™” ํ•ด๋‚˜์•„๊ฐ€๋Š” ๊ณผ์ •์—์„œ ์™œ ์ƒํƒœ๊ด€๋ฆฌ๋ฅผ ํ•˜๊ณ  ์žˆ์ง€ ๋ผ๋Š” ์˜๋ฌธ์ด ๋“ค๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค

Main

01. ์ƒํƒœ๋ž€ ๋ฌด์—‡์ผ๊นŒ?

๊ทผ๋ณธ์ ์œผ๋กœ ์ƒํƒœ๋ž€ ๋ฌด์—‡์ธ์ง€ ์ƒ๊ฐํ•ด๋ณด๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ์ƒํƒœ๋Š” ๋ฌด์–ธ๊ฐ€์˜ ๋ชจ์–‘์ด๋‚˜ ํ˜•ํŽธ์„ ๋œปํ•ด์š”! ์˜ˆ์‹œ๋ฅผ ๋“ค์ž๋ฉด Garden์€ ์˜ค๋Š˜ ํ–‰๋ณตํ•œ ์ƒํƒœ์•ผ ;) or ์ด๋ฏธ ์™•์‹ญ๋ฆฌ์—ญ์—๋Š” ๋ง‰์ฐจ๊ฐ€ ๋Š๊ธด ์ƒํƒœ ๊ฐ€ ๋  ์ˆ˜ ์žˆ๊ฒ ๋„ค์š”

๊ทธ๋Ÿผ ๊ฐœ๋ฐœ์—์„œ์˜ ์ƒํƒœ๋ž€ ์–ด๋–ค ๊ฒŒ ๋  ์ˆ˜ ์žˆ์„๊นŒ์š”?

export const ButtonStyles: CssArchiveType = {
  default: css`
    display: flex;
    align-items: center;
    justify-content: center;

    border-radius: 12px;
    border: none;
    cursor: pointer;
    background-color: ${Colors.Primary};
    color: ${Colors.White};
  `,
  `,
...
}

์œ„์˜ ์Šคํƒ€์ผ ์ฝ”๋“œ๋ฅผ ๋ด๋„ ์•Œ ์ˆ˜ ์žˆ๋“ฏ์ด, ์™ผ์ชฝ์€ ์ƒํƒœ์˜ ๋„ค์ด๋ฐ์ด๋‚˜ ํ•„๋“œ๋ฅผ ํ‘œ๊ธฐํ•˜๊ณ  ์žˆ๊ณ , ์˜ค๋ฅธ์ชฝ์—๋Š” ๊ทธ๋•Œ์˜ ์ƒํƒœ๋ฅผ ์ž‘์„ฑํ•ด์ฃผ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‹ˆ๊นŒ
background-color: ${Colors.Primary} ๋ฅผ ๋ณด๋ฉด ๋ฐฐ๊ฒฝ์ƒ‰์€ ${Colors.Primary} ์ƒํƒœ๋กœ ์ง€์ •ํ•ด ๋ผ๋Š” ์˜๋ฏธ๋กœ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์šฐ๋ฆฌ๊ฐ€ ๊ฐœ๋ฐœ์„ ํ•˜๊ธฐ ์ „์— "์–ด๋Š ๋ถ€๋ถ„์—์„œ ์ƒํƒœ๊ฐ€ ํ•„์š”ํ•˜๊ณ  ์–ด๋–ค ์ƒํƒœ๊ฐ€ ํ•„์š”ํ•  ์ง€" ์ƒ๊ฐํ•ด๋ณด๋Š” ๊ณผ์ •์„ ๊ฐœ๋ฐœ ์„ค๊ณ„์— ๋“ค์–ด๊ฐ€๋ฉด ์ข‹์„ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

02. ์ƒํƒœ์˜ ์˜ฌ๋ฐ”๋ฅธ ์ดˆ๊ธฐ ๊ฐ’

์ž ์ด์ œ ๋ณธ๊ฒฉ์ ์œผ๋กœ ์ƒํƒœ์˜ ์˜ฌ๋ฐ”๋ฅธ ์ดˆ๊ธฐ๊ฐ’์„ ์„ค์ •ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.
๋จผ์ € ์ดˆ๊ธฐ ๊ฐ’ ์ด๋ž€, ๋ฆฌ์•กํŠธ์—์„œ ํ•˜๋‚˜์˜ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ Œ๋”๋งํ•˜๋Š”๋ฐ ์—ฌ๋Ÿฌ ์ผ์ด ๋ฐœ์ƒํ•˜๊ณ , ๋‚ด๊ฐ€ ์ƒ๊ฐํ•œ ๋Œ€๋กœ ๋™์ž‘ํ•˜์ง€ ์•Š์•„ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ฝ”๋“œ๋กœ ์‚ดํŽด๋ณด์ž๋ฉด,

function getData () {
  const [data, setData] = useState();
  
  useEffect (() => {
    const fetchData = async () => {
      
      const response = await fetch("https://api.example.com");
      const result = await response.json();
      setData(result);
    };
    
    fetchData();
    
  }, []);
  
  return (
    {data.map((item) => (
    	~~
    }
    );
}

์œ„์˜ ์ดˆ๊ธฐ ๊ฐ’ ์„ ์–ธ์—์„œ๋Š” useState์•ˆ์— ์•„๋ฌด๊ฒƒ๋„ ์—†์œผ๋ฏ€๋กœ ์•„๋ฌด ๊ฐ’๋„ ์„ค์ •๋˜์–ด์žˆ์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
๊ทธ๋ฆฌ๊ณ  fetchData๋ผ๋Š” ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰์ด ๋˜๋ฉด ๊ทธ์ œ์„œ์•ผ setData๊ฐ€ ๋˜๋ฉด์„œ data์•ˆ์— ๊ฐ’์ด ๋“ค์–ด๊ฐ€๊ฒŒ๋ฉ๋‹ˆ๋‹ค.
return๋ฌธ ์•ˆ์—์„œ data๋ฅผ ์ž˜ ๋ฐ›์•„์™€ ๋„ฃ์œผ๋ฉด ์ž˜ ์‹คํ–‰๋œ๋‹ค๊ณ  ๋ณผ ์ˆ˜ ์žˆ๊ธฐ๋„ ํ•˜๊ฒ ์ง€๋งŒ
๋ฐ›์•„์˜จ ๋ฐ์ดํ„ฐ๋ฅผ ๋ Œ๋”๋งํ•˜๋Š”๋ฐ ๋ฐ์ดํ„ฐ๊ฐ€ ์—†์–ด์„œ .map()์„ array์˜ ํ”„๋กœํ† ํƒ€์ž…์—์„œ ๊ฐ€์ ธ์˜ค๋Š” ์ˆœ๊ฐ„์˜ ์ฐจ์ด ๋•Œ๋ฌธ์— ๋ Œ๋”๋ง ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.
๋”ฐ๋ผ์„œ ๋ฌด์˜๋ฏธํ•œ ์ฝ”๋“œ๊ฐ€ ๋“ค์–ด๊ฐ€๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด์„œ, array๊ฐ€ ๋งž๋Š”์ง€ data๋ฅผ ๋จผ์ € ํ™•์ธํ•ด์•ผํ•˜๋Š” ์ฝ”๋“œ๊ฐ€ ์„ ์–ธ๋˜์–ด์•ผํ•ฉ๋‹ˆ๋‹ค. ์•„๋ž˜์™€ ๊ฐ™์ด ๊ณ ์ณ๋ณผ ์ˆ˜ ์žˆ๊ฒ ๋„ค์š”!

    {Array.isArray(data) && data.map((item) => (
    	~~
    }

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

  const [data, setData] = useState([]);

๋ฆฌ์•กํŠธ ๋ Œ๋”๋ง์€ ์šฐ๋ฆฌ๊ฐ€ ์ƒ๊ฐํ•˜๋Š” ๊ฒƒ๊ณผ ๋‹ค๋ฅด๊ฒŒ ์—ฌ๋Ÿฌ ๋ฒˆ ๋ฐœ์ƒ๋˜๊ณ  ์†๋„๊ฐ€, ์ˆœ์„œ๊ฐ€ ์ œ๊ฐ๊ฐ์ด๊ธฐ์— ์ดˆ๊ธฐ ๊ฐ’์ด ์ •๋ง ์ค‘์š”ํ•˜๋‹ค๋Š” ๊ฒƒ์„ ๊นจ๋‹ซ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  useState๋ฅผ ๋น„์›Œ๋‘๊ฒŒ ๋œ๋‹ค๋ฉด ๊ทธ ๋ณ€์ˆ˜์— ๋“ค์–ด๊ฐ€๋Š” ๊ฐ’์€ undefined๊ฐ€ ๋˜๋‹ˆ ํ•ญ์ƒ ์ดˆ๊ธฐ๊ฐ’ ์„ค์ •์— ์ฃผ์˜ํ•˜๋„๋ก ํ•ฉ์‹œ๋‹ค.

๋”ฐ๋ผ์„œ ์ด ์งˆ๋ฌธ์˜ ์‹œ์ž‘์ธ ์ดˆ๊ธฐ ๊ฐ’์ด๋ž€,

  • ๊ฐ€์žฅ ๋จผ์ € ๋ Œ๋”๋ง ๋  ๋•Œ ์ˆœ๊ฐ„์ ์œผ๋กœ ๋ณด์—ฌ์งˆ ์ˆ˜ ์žˆ๋Š” ๊ฐ’
  • ์ดˆ๊ธฐ์— ๋ Œ๋”๋ง ๋˜๋Š” ๊ฐ’

์œผ๋กœ ์ •๋ฆฌํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

์ด๋ฅผ ์ง€ํ‚ค์ง€ ์•Š๋Š”๋‹ค๋ฉด? -> ๋ Œ๋”๋ง ์ด์Šˆ, ๋ฌดํ•œ ๋ฃจํ”„, ํƒ€์ž… ๋ถˆ์ผ์น˜๋กœ ์˜๋„์น˜ ์•Š์€ ๋™์ž‘ -> ๋Ÿฐํƒ€์ž„ ์—๋Ÿฌ ๋ฐœ์ƒํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

๋˜ํ•œ ์ดˆ๊ธฐ๊ฐ’ ์ž˜ ์„ค์ •ํ•ด์ค€๋‹ค๋ฉด ๋นˆ๊ฐ’์ด๋‚˜ null ์ฒ˜๋ฆฌ๋ฅผ ํ•  ๋•Œ ๋ถˆํ•„์š”ํ•œ ๋ฐฉ์–ด์ฝ”๋“œ๋„ ์ค„์—ฌ ๋” ์•ˆ์ „ํ•œ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๊ฐœ๋ฐœํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

03. ์—…๋ฐ์ดํŠธ ๋˜์ง€ ์•Š๋Š” ๊ฐ’

์ด๋ฒˆ์—๋Š” ๋ณ€์ˆ˜๋ฅผ ๋ฆฌ์•กํŠธ ์ปดํฌ๋„ŒํŠธ ๋‚ด๋ถ€์— ์ง์ ‘์ ์œผ๋กœ ๊ฐ€์ง€๊ณ  ์žˆ์„ ๋•Œ์— ๋Œ€ํ•ด ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

function NotUpdataValue() : Element {
  const INFO = {
    name: 'My Component',
	value: 'Clean Code React',

	const [ count, setCount] = useState(0);

	return(
      <div className = "App">
      	<header>{INFO}</header> // child
		<ShowCount info={INFO} count={count} /> //props
	  </div>
   );
}

์œ„์˜ ํ•จ์ˆ˜ ์„ ์–ธ๋ถ€๋ฅผ ๋ณด๋ฉด INFO๋ผ๋Š” ๊ฐ์ฒด๊ฐ€ ์„ ์–ธ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฐ ๊ฒฝ์šฐ๋Š” ์ƒ์ˆ˜๋ฅผ ๋‹ค๋ฃจ๊ฑฐ๋‚˜, ์ผ๋ฐ˜์ ์ธ ๋ฐฉ์น˜๊ฐ€ ๊ฐ€์žฅ ํ”ํ•œ ๊ฒฝ์šฐ์ž…๋‹ˆ๋‹ค. ์ด ๊ฐ์ฒด๋Š” ํ˜„์žฌ return๋ฌธ ์ „์— ์–ด๋–ค ๋ถ€๋ถ„์—์„œ๋„ ์‚ฌ์šฉ๋˜๊ณ  ์žˆ์ง€ ์•Š๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฆ‰ ์ด ๊ฐ์ฒด์— ์žˆ๋Š” ์†์„ฑ์„ ๋ฐ”๊พธ๋Š” ๊ฒฝ์šฐ๊ฐ€ ์ „ํ˜€ ์žˆ์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ฆ‰ INFO ๊ฐ์ฒด๋Š” ํ˜„์žฌ ์—…๋ฐ์ดํŠธ๊ฐ€ ๋˜์ง€ ์•Š๋Š” ์ผ๋ฐ˜์ ์ธ ๊ฐ์ฒด๋ผ๊ณ  ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ return ๋ฌธ ์•ˆ์—์„œ ๋ณด๋ฉด header์—์„œ๋Š” child๋กœ, ShowCount์—์„œ๋Š” ํ•˜๋‚˜์˜ props๋กœ ๊ฐ์ฒด๋ฅผ ๋‚ด๋ฆฌ๊ณ  ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ๋Š” ๋ถ€์ ์ ˆํ•œ ๊ฒฝ์šฐ์ธ๋ฐ, ๊ทธ ์ด์œ ๋Š” ๋ฆฌ์•กํŠธ ์ปดํฌ๋„ŒํŠธ ๋‚ด๋ถ€์— ์žˆ๋Š” ์• ๋“ค์ธ๋ฐ ๋งค๋ฒˆ ๋ Œ๋”๋ง์ด ๋  ๋•Œ๋งˆ๋‹ค ๊ฐ™์€ ๊ฐ’์ด๋”๋ผ๋„ ๋ถˆํ•„์š”ํ•˜๊ฒŒ ์ฐธ์กฐํ•˜๊ณ  ์žˆ๋Š” ์ƒํƒœ์ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

์œ„์˜ ๊ฒฝ์šฐ๋Š” 2๊ฐ€์ง€ ๊ฒฝ์šฐ๋กœ ๋ฆฌํŒฉํ† ๋ง์„ ํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ ๋ฐ”๋กœ ๋ฆฌ์•กํŠธ ์ƒํƒœ๋กœ ๋ณ€ํ™˜ or ์™ธ๋ถ€๋กœ ๋‚ด๋ณด๋‚ด๊ธฐ ์˜ ๋ฐฉ๋ฒ•์„ ๊ณ ์•ˆํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์•„์˜ˆ ์ปดํฌ๋„ŒํŠธ ์™ธ๋ถ€๋กœ ๋นผ๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค :)

  const INFO = {
    name: 'My Component',
	value: 'Clean Code React',
  }

function NotUpdataValue() : Element {
	const [ count, setCount] = useState(0);

	return(
      <div className = "App">
      	<header>{INFO}</header> // child
		<ShowCount info={INFO} count={count} /> //props
	  </div>
   );
}

04. ๋ถˆํ•„์š”ํ•œ ์ƒํƒœ ์ œ๊ฑฐํ•˜๊ธฐ

์ด์ œ๋Š” ์ดˆ๊ธฐ๊ฐ’์„ ๋ฐ”๊ฟ”์•ผํ•˜๋Š” ๊ฒฝ์šฐ๋‚˜ ๊ฐ’์ด ๋ณ€ํ•˜๋Š” ๊ฒฝ์šฐ๋ฅผ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.


const Mock_data = [
  {
    userId: 1,
    id: 1,
    title: 'clean code',
    completed: false
  },
  {
    userId: 2,
    id: 2,
    title: 'funny code',
    completed: true
  },
...
  ]
  
function NotUnessState() {
const [userList, setUserList] = useState(Mock_data) //์ดˆ๊ธฐ ์ƒํƒœ ์„ ์–ธ
const [complUserList, setComplUserList] = useState(Mock_data) //๋ณ€๊ฒฝ ํ›„ ์ €์žฅํ•  ์ƒํƒœ ์„ ์–ธ

}

์œ„์™€ ๊ฐ™์ด ์™„๋ฃŒํ•œ ์ผ๋งŒ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ์œ ์ €๋ฆฌ์ŠคํŠธ๋ฅผ ์ƒ์„ฑํ•ด๋ณด์•˜์Šต๋‹ˆ๋‹ค. Mock_data์—์„œ completed๊ฐ€ true์ธ ํ•ญ๋ชฉ๋“ค๋งŒ list๋กœ ๋ฐ”๊พธ๊ณ  ์‹ถ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.


const [complUserList, setComplUserList] = useState(Mock_data) 

useEffect((): void => {
  const newList = complUserList.filter(user) : boolean => user.completed === true);
  setUserList(newList);
},[userList];

์ด๋ ‡๊ฒŒ ์กฐ๊ฑด์„ ์„ค์ •ํ•ด ์ž‘์„ฑํ•ด๋ณด์•˜๋Š”๋ฐ ์ด๊ฒƒ๋„ ๋น„ํšจ์œจ์ ์ธ ์ฝ”๋“œ๋ผ๊ณ  ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์œ„์˜ ์ฝ”๋“œ๋ฅผ useEffect() ๋ฐ–์œผ๋กœ ๋นผ์„œ ๋‚ด๋ถ€์˜ ๋ณ€์ˆ˜๋กœ ์„ ์–ธํ•˜๊ฒŒ ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.


const complUserList  = complUserList.filter(user) : boolean => user.completed === true);

๋ Œ๋”๋ง ๋  ๋•Œ๋งˆ๋‹ค ๊ฐ’์ด ๋ฐ”๋€Œ๊ณ  ๊ด€์—ฌ๋˜์ง€๋งŒ ์ด ๊ฐ’์€ ๊ตณ์ด ์ƒํƒœ๋กœ ๋งŒ๋“ค ํ•„์š”๊ฐ€ ์—†๋‹ค๊ณ  ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๊ฒฐ๊ตญ ๋ Œ๋”๋ง ์‹œ ๊ณ ์œ ์˜ complUserList ๊ฐ€ ์ƒ์„ฑ๋˜๊ธฐ ๋•Œ๋ฌธ์— ๊ด€๋ฆฌํ•  ํ•„์š”๋„ ์—†๊ณ  setํ•  ํ•„์š”๋„ ์—†๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

์ €๋Š” ์ด๋•Œ ์ปดํฌ๋„ŒํŠธ ๋‚ด๋ถ€์— ์„ ์–ธ๋œ ๋ณ€์ˆ˜๋ฅผ ์–ด๋–ค ์—ญํ• ์„ ํ•˜๋Š”์ง€ ๊ถ๊ธˆํ–ˆ๋Š”๋ฐ์š”,
์ปดํฌ๋„ŒํŠธ ๋‚ด๋ถ€์—์„œ์˜ ๋ณ€์ˆ˜๋Š” ๋ Œ๋”๋ง ๋งˆ๋‹ค ๊ณ ์œ ์˜ ๊ฐ’์„ ๊ฐ€์ง€๋Š” ๊ณ„์‚ฐ๋œ ๊ฐ’์„ ๊ฐ€์ง„๋‹ค๋ผ๊ณ  ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ฒฐ๋ก ์ ์œผ๋กœ ์šฐ๋ฆฌ๊ฐ€ ๋ถˆํ•„์š”ํ•œ ์ƒํƒœ๋ฅผ ๋งŒ๋“ ๋‹ค๋ฉด?
๊ฒฐ๊ตญ์—๋Š” ๋ฆฌ์•กํŠธ์— ์˜ํ•ด ๊ด€๋ฆฌ๋˜๋Š” ๊ฐ’์ด ๋Š˜์–ด๋‚˜๋Š” ๊ฒƒ์ด๊ณ ,
๊ทธ๋Ÿฌ๋‹ค๋ณด๋ฉด ๋ Œ๋”๋ง์— ์˜ํ–ฅ์„ ์ฃผ๋Š” ๊ฐ’์ด ๋Š˜์–ด๋‚˜์„œ ๊ด€๋ฆฌ ํฌ์ธํŠธ๊ฐ€ ๋”๋”์šฑ ๋Š˜์–ด๋‚˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

05. useState๋ฅผ ๋Œ€์‹ ํ•˜์—ฌ useRef

์ปดํฌ๋„ŒํŠธ์˜ ์ „์ฒด์ ์ธ ์ˆ˜๋ช…๊ณผ ๋™์ผํ•˜๊ฒŒ ์ง€์†๋œ ์ •๋ณด๋ฅผ ์ผ๊ด€์ ์œผ๋กœ ์ œ๊ณตํ•ด์•ผํ•˜๋Š” ๊ฒฝ์šฐ์—๋Š” useState ๋Œ€์‹ ์— useRef๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ตฌํ˜„ํ•  ์ˆ˜๋„ ์žˆ๋Š”๋ฐ์š”! ๊ฒฐ๊ตญ ๋ฆฌ๋ Œ๋”๋ง ๋ฐฉ์ง€๊ฐ€ ํ•„์š”ํ•  ๋•Œ useRef๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

useState๋ฅผ ํ†ตํ•ด ๊ฐ’์ด ๋งŒ๋“ค์–ด์ง€๋ฉด setState๊ฐ€ ๋™์ž‘์„ ํ•˜๋ฉด์„œ ์›ํ•˜์ง€ ์•Š๋Š” ๋ฆฌ๋ Œ๋”๊ฐ€ ์ปดํฌ๋„ŒํŠธ์— ๋ฐœ์ƒ๋˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ๋ฆฌ๋ Œ๋”๊ฐ€ ๋˜์ง€ ์•Š๊ณ  ์ดˆ๊ธฐ๊ฐ’์„ ๋‚˜ํƒ€๋‚ด๊ฑฐ๋‚˜ ๋ฆฌ๋ Œ๋”๊ฐ€ ๊ตณ์ด ๋˜์ง€ ์•Š๊ณ  ๋ Œ๋”๋ง ํ”„๋กœ์„ธ์Šค์™€ ๊ด€๊ณ„์—†์ด ๊ฐ’์„ ๊ฐ€๋ณ€์ ์œผ๋กœ ์ €์žฅํ•˜๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ ๊ทธ๋•Œ๋Š” useRef๋ฅผ ๊ณ ๋ คํ•˜๋Š”๊ฒŒ ์ข‹์„ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

๋จผ์ € useState๋กœ ์‚ฌ์šฉ์ž์˜ ์ž…๋ ฅ์„ ์ถ”์ ํ•˜๊ณ  ํ™”๋ฉด์— ํ‘œ์‹œํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ ์˜ˆ์‹œ๋ฅผ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

import { useState } from 'react';

function InputComponent() {
  const [inputValue, setInputValue] = useState('');

  const handleChange = (event) => {
    setInputValue(event.target.value);
  };

  return (
    <div>
      <input type="text" value={inputValue} onChange={handleChange} />
      <p>์ž…๋ ฅ๊ฐ’: {inputValue}</p>
    </div>
  );
}

export default InputComponent;

์œ„์˜ ์ฝ”๋“œ์—์„œ๋Š” inputValue ์ƒํƒœ๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ๋งˆ๋‹ค ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ฆฌ๋ Œ๋”๋ง๋˜๊ณ , ์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅ ํ•„๋“œ์— ๋ฌธ์ž๋ฅผ ์ž…๋ ฅํ•  ๋•Œ๋งˆ๋‹ค setInputValue ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋˜์–ด ์ƒํƒœ๊ฐ€ ๊ฐฑ์‹ ๋˜๊ณ , ์ด๋กœ ์ธํ•ด ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ƒˆ๋กœ ๋ Œ๋”๋ง ๋ฉ๋‹ˆ๋‹ค.

์ด์ œ๋Š” useRef๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋ฆฌ๋ Œ๋”๋ง์„ ์œ ๋ฐœํ•˜์ง€ ์•Š์œผ๋ฉด์„œ ๊ฐ’์ด ์œ ์ง€๋˜๋Š” ref๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•ด ์ƒํƒœ์˜ ๋ณ€๊ฒฝ์„ ์ถ”์ฒ™ํ•˜๋ฉด์„œ ์ปดํฌ๋„ŒํŠธ์˜ ๋ถˆํ•„์š”ํ•œ ๋ฆฌ๋ Œ๋”๋ง์„ ๋ฐฉ์ง€ํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

import { useRef } from 'react';

function InputComponentWithRef() {
  const inputValueRef = useRef('');

  const handleChange = (event) => {
    inputValueRef.current = event.target.value;
    console.log(`์ž…๋ ฅ๊ฐ’: ${inputValueRef.current}`);
  };

  return (
    <div>
      <input type="text" onChange={handleChange} />
    </div>
  );
}

export default InputComponentWithRef;

์œ„์˜ ์ฝ”๋“œ์—์„œ๋Š” inputValueRef๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ž…๋ ฅ๊ฐ’์„ ์ถ”์ ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฒŒ๋‹ค๊ฐ€ useRef๋Š” ์ปดํฌ๋„ŒํŠธ์˜ ๋ฆฌ๋ Œ๋”๋ง์„ ๋ฐœ์ƒ์‹œํ‚ค์ง€ ์•Š์œผ๋ฏ€๋กœ handleChange ํ•จ์ˆ˜ ๋‚ด์—์„œ ์ž…๋ ฅ๊ฐ’์ด ๊ฐฑ์‹ ๋˜์–ด๋„ ํ™”๋ฉด์ด ์ƒˆ๋กœ ๋ Œ๋”๋ง ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ผญ DOM์— ๋ถ™์—ฌ์„œ ์“ฐ๋Š” ๊ฒƒ๋งŒ์ด ref ์‚ฌ์šฉ์— ๋‹ค๋Š” ์•„๋‹ˆ๋‹ค๋ผ๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

06. useState ๋Œ€์‹ ์— useReducer

์—ฌ๋Ÿฌ ์ƒํƒœ๋“ค ์ค‘์—์„œ ๊ตฌ์กฐํ™”๋œ ์ƒํƒœ๋ฅผ ์›ํ•˜๋ฉด useReducer๋ฅผ ์‚ฌ์šฉํ•ด๋ณด๋Š” ๊ฑธ ๊ณ ๋ คํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ €๋Š” useReducer๋ฅผ ์ฒ˜์Œ ๋ดค์„ ๋•Œ ๋ฆฌ๋•์Šค๋ž‘ ๋น„์Šทํ•˜๋‹ค๋Š” ์ƒ๊ฐ์„ ํ–ˆ์—ˆ๋Š”๋ฐ์š”, ์•Œ๊ณ ๋ณด๋‹ˆ ๋ฌธ๋ฒ•์ด ์œ ์‚ฌํ•˜๋‹ค๋Š” ๊ฒƒ์„ ๊นจ๋‹ฌ์•˜์Šต๋‹ˆ๋‹ค ํ•˜ํ•˜ ์ฝ”๋“œ๋กœ ํ•œ ๋ฒˆ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

const INIT_STATE = {
	isLoading: false,
    isSuccess: false,
    isFail: false,
}

function StateToReducer(){
  const [state, dispatch]= useReducer(reducer, INIT_STATE)

์—ฌ๊ธฐ์„œ ์ž ๊น reducer ์ž‘์„ฑ ๋ฐฉ๋ฒ•์„ ์‚ดํŽด๋ณด๋ฉด, ๋จผ์ € useReducer()์ด๋ผ๋Š” ํ•จ์ˆ˜๋ฅผ ๋จผ์ € ๊ฐ€์ ธ์˜ค๊ณ 
๋งˆ์ฐฌ๊ฐ€์ง€๊ณ  ๋ฐฐ์—ด ๊ตฌ์กฐ ๋ถ„ํ•ด ํ• ๋‹นํ•ด์„œ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. ์œ„์˜ ์ฝ”๋“œ์—์„œ state๋ฅผ ๊ฐ€์ ธ์˜ค๊ณ  ์ด ์ƒํƒœ๋ฅผ setํ•˜๋Š” dispatch๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.
์ฒซ ๋ฒˆ์งธ ์ธ์ž๋กœ๋Š” reducer๋ฅผ ๊ฐ€์ ธ์˜ค๊ณ  ์ด๋Š” ์กฐ์ž‘ํ•˜๋Š” ํ•จ์ˆ˜๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. ๋‘ ๋ฒˆ์งธ ์ธ์ž์—๋Š” ์ดˆ๊ธฐ๊ฐ’์„ ๋„ฃ์„ ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

์—ฌ๊ธฐ์„œ reducer callback์œผ๋กœ ํ˜„์žฌ ์ƒํƒœ์™€ ์ด ์ƒํƒœ๋ฅผ ๋ณ€ํ™”ํ•  ์ˆ˜ ์žˆ๋Š” ์•ก์…˜์„ ๋ฐ›๋Š” reducer๋ฅผ ์„ ์–ธํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

...

const reducer = (state, action) =>{
  switch (action.type){
    case 'FETCH_LOADING':
      return { isLoading: true, isSuccess: false, isFail: false} 
    case 'FETCH_SUCCESS': 
      return { isLoading: false, isSuccess: true, isFail: false} 
    case 'FETCH_FAIL': 
      return { isLoading: false, isSuccess: false, isFail: true} 
    defalt:
      return INIT_STATE
} 
function StateToReducer(){
  const [state, dispatch]= useReducer(reducer, INIT_STATE)

๋จผ์ € ํ•ด๋‹น ์•ก์…˜์˜ type์„ ๋ฐ›์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  swich ๋ฌธ์œผ๋กœ ๊ฐ๊ฐ์˜ ์กฐ๊ฑด์— ๋งž๊ฒŒ ๋ฐ”๋€” ๊ฐ’์„ ์ง์ ‘ ๋ช…์‹œํ•ด์ค๋‹ˆ๋‹ค.

๊ทธ ๋‹ค์Œ์— ํ•จ์ˆ˜ ๋‚ด๋ถ€์—์„œ dispatch๋ฅผ ํ˜ธ์ถœํ•˜๊ณ , ํƒ€์ž…์— ์šฐ๋ฆฌ๊ฐ€ ์ •์˜ํ•œ๊ฒƒ์„ ๋„ฃ์–ด์ฃผ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

...

function StateToReducer(){
  const [state, dispatch]= useReducer(reducer, INIT_STATE)
  
  const fetchData = () => {
    dispatch({ type: 'FETCH_LOADING'})
    ... ๋™์ผํ•˜๊ฒŒ ใ„ฑใ„ฑ

์ด๋ ‡๊ฒŒ ๋ฆฌํŒฉํ† ๋งํ•˜๋ฉด ์ƒํƒœ๋ฅผ ์„ธ๋ฐ€ํ•˜๊ฒŒ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๊ณ , reducer ํ•จ์ˆ˜๋ฅผ ์ž‘์„ฑํ•œ ๋ถ€๋ถ„์€ ์ˆœ์ˆ˜ํ•œ js ๋ฌธ๋ฒ•์ด๊ธฐ ๋•Œ๋ฌธ์— react์— ์˜์กด์ ์ธ ์ฝ”๋“œ๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค.

useReducer๋Š” ์ƒํƒœ๋ฅผ ํ•˜๋‚˜ํ•˜๋‚˜ ์กฐ์ž‘ํ•˜๊ณ , ๋กœ์ง์ด ์–ฝํ˜€์žˆ๋Š” ๋ถ€๋ถ„์„ ๋‹ค ์ถ”์ƒํ™” ํ•ด์ค๋‹ˆ๋‹ค. action type๋งŒ ํ˜ธ์ถœํ•˜๋ฉด ๊ทธ ์•ˆ์˜ ๋‚ด๋ถ€ ๋กœ์ง์ด ๋ชจ๋‘ ์ถ”์ƒํ™” ๋˜์–ด์žˆ๊ธฐ ๋•Œ๋ฌธ์— ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ตฌ๋ฌธ์—์„œ๋Š” ๋‚ด๋ถ€์— ๋ญ๊ฐ€ ์žˆ๋Š”์ง€ ๋ชฐ๋ผ๋„ action type๋งŒ ๋ณด๊ณ ๋„ ์ถ”์ •ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์žฅ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

07. ์ƒํƒœ๋กœ์ง์„ Custom Hooks๋กœ ๊บผ๋‚ด๊ธฐ

์šฐ๋ฆฌ๋Š” ํ•ญ์ƒ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๊ฐœ๋ฐœํ•  ๋•Œ, ํ™”๋ฉด์— ๋ Œ๋”๋ง ๋˜๋Š” ์ฝ”๋“œ๋งŒ ๋‚จ๊ธฐ๊ณ , ๋กœ์ง์— ๊ด€๋ จ๋œ ๋ถ€๋ถ„๋งŒ ๋นผ๋ณด๋Š” ๋ฆฌํŒฉํ† ๋ง์ด ์ค‘์š”ํ•œ๋ฐ์š”! ์ด๋•Œ custom hook์„ ์‚ฌ์šฉํ•ด ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ฐ„๋‹จํ•œ ์‚ฌ์šฉ์ž ์ž…๋ ฅ์„ ์ฒ˜๋ฆฌํ•˜๋Š” ์ƒํƒœ๋กœ์ง์ด ๊ตฌํ˜„๋œ ์˜ˆ์‹œ ์ฝ”๋“œ๋กœ ๋จผ์ € ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

import { useState } from 'react';

function useInputHooks(initialValue) {
  const [value, setValue] = useState(initialValue);

  const handleChange = (event) => {
    setValue(event.target.value);
  };

  return [value, handleChange];
}

์—ฌ๊ธฐ์„œ useInputHooks์ด๋ผ๋Š” ์ปค์Šคํ…€ ํ›…์„ ๋งŒ๋“ค์–ด ์ž…๋ ฅ ๊ฐ’์„ ๊ด€๋ฆฌํ•˜๊ณ , ์ด ์ž…๋ ฅ ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜๋Š” ํ•จ์ˆ˜์™€ ์ž…๋ ฅ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๋„๋ก ์ฝ”๋“œ๋ฅผ ๊ตฌํ˜„ํ–ˆ์Šต๋‹ˆ๋‹ค.

import React from 'react';
import  useInputHooks from './hooks/useInputHooks';

function InputComponent() {
  const [inputValue, handleInputChange] = useInput('');

  return (
    <div>
      <input type="text" value={inputValue} onChange={handleInputChange} />
      <p>์ž…๋ ฅ๊ฐ’: {inputValue}</p>
    </div>
  );
}

export default InputComponent;

์œ„์˜ ์ฝ”๋“œ์—์„œ๋Š” ์•ž์„œ์„œ ๋งŒ๋“  useInputHooks๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์‚ฌ์šฉ์ž์˜ ์ž…๋ ฅ ํ•„๋“œ์˜ ์ƒํƒœ๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค. useInputHooks๋ฅผ ์ด ์ปดํฌ๋„ŒํŠธ ๋ฟ๋งŒ์•„๋‹ˆ๋ผ ๋‹ค๋ฅธ ์ปดํฌ๋„ŒํŠธ์—์„œ๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ธฐ๋•Œ๋ฌธ์— ์ฝ”๋“œ๋ฅผ ํ™•์žฅ์„ฑ์žˆ๊ณ  ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๊ฒŒ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค!

End.

์˜ค๋Š˜ ์ด ํฌ์ŠคํŒ…์„ ์ž‘์„ฑํ•˜๋ฉด์„œ "๋‹น์—ฐํ•˜๊ฒŒ ์ž‘์„ฑํ–ˆ๋˜ ๊ฒƒ๋“ค" ์— ๋Œ€ํ•ด์„œ ๋ผ์ด๋ธŒ ์ฝ”๋”ฉ์„ ํ•ด๋ณด๋ฉด์„œ ์Šต๊ด€์˜ ์˜์กด์„ฑ์„ ๋ฐ˜์„ฑ์„ ํ•˜๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ๋ง๋กœ ์„ค๋ช…ํ•˜๋‹ค๋ณด๋‹ˆ ์ œ๊ฐ€ ๋ชฐ๋ž๋˜ ๋ถ€๋ถ„์— ๋Œ€ํ•ด์„œ ์ •ํ™•ํžˆ ์งš๊ณ  ๊ฐˆ์ˆ˜ ์žˆ์—ˆ๊ณ 
ํŠนํžˆ reducer ๋ถ€๋ถ„์ด ํšŒ์‚ฌ์—์„œ๋Š” ์ดํ•ดํ•˜๊ธฐ ์˜ค๋ž˜ ๊ฑธ๋ ธ๋Š”๋ฐ ๋ฌธ๋ฒ• ์ฑ…์„ ๋ณด๊ณ  ํ•˜๋‚˜ํ•˜๋‚˜ ์ง์ ‘ ์Œฉ ์ฝ”๋”ฉ์„ ํ•ด๋ณด๋‹ˆ๊นŒ ๋™์ž‘์›๋ฆฌ๋ฅผ ์•Œ์•„๊ฐ€๊ฒŒ ๋  ์ˆ˜ ์žˆ์—ˆ๋˜ ์‹œ๊ฐ„์ด์—ˆ์Šต๋‹ˆ๋‹ค.
์ด์ œ๋ถ€ํ„ฐ๋Š” ๋Œ€๋ถ€๋ถ„ useState()์— ์ต์ˆ™ํ–ˆ๋˜ ์‹œ๊ฐ„์„ ์กธ์—…ํ•˜๊ณ  ์ข€ ๋” ๋‚˜์€ hooks ๋“ค๋กœ ํด๋ฆฐ์ฝ”๋“œ๋ฅผ ์งœ๋Š” ์—ฐ์Šต์„ ํ•˜๋Š”๊ฒŒ ์ค‘์š”ํ•  ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค ๐Ÿ”ฅ ๐Ÿ”ฅ

profile
Garden / Junior Frontend Developer

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