ย ๐Ÿš€ SetState์— prevState๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ 

dwellยท2022๋…„ 7์›” 11์ผ
6

State ์™€ useState ?


state (์ƒํƒœ)๋Š” ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋Š” ๋ณ€๊ฒฝ ๊ฐ€๋Šฅํ•œ ๋ฐ์ดํ„ฐ๋‹ค.

๋ฆฌ์•กํŠธ 16.8 ์ด์ „์—๋Š” ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ƒํƒœ๋ฅผ ๊ฐ–๊ธฐ ์œ„ํ•ด์„œ ํด๋ž˜์Šคํ˜• ์ปดํฌ๋„ŒํŠธ๋งŒ ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ–ˆ๋‹ค.

ํ•˜์ง€๋งŒ 16.8 ์ดํ›„๋ถ€ํ„ฐ hook์„ ์ด์šฉํ•ด์„œ ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ๋„ ์ƒํƒœ๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ๋‹ค.

๊ทธ hook์ด ๋ฐ”๋กœ useState ๋‹ค.

useState๋Š” ์ƒํƒœ์™€ ๊ทธ ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋Š” setํ•จ์ˆ˜๋ฅผ ๋ฆฌํ„ดํ•œ๋‹ค.

useState์˜ ์ธ์ž๋กœ๋Š” ์ƒํƒœ์˜ ์ดˆ๊ธฐ๊ฐ’์ด ๋“ค์–ด๊ฐ„๋‹ค.

๊ธฐ๋ณธ์ ์ธ ๋ฌธ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

import React, {useState} from 'react'

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

	return (
	  <h1>Count : {count}</h1>
	)
}

export default Counter;

SetState ํ•จ์ˆ˜์™€ prev


setState๋Š” useState์˜ ๋ฆฌํ„ด๊ฐ’์œผ๋กœ state๋ฅผ ์—…๋ฐ์ดํŠธํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ํ•จ์ˆ˜์ด๋‹ค.

์ด๋•Œ, ๋ณดํ†ต setState์—์„œ state๋ฅผ ์ง์ ‘์ ์œผ๋กœ ์‚ฌ์šฉํ•˜์—ฌ ์—…๋ฐ์ดํŠธ๋ฅผ ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋‹ค.

์ด๋Š” ํ‹€๋ฆฐ ๋ฐฉ์‹์€ ์•„๋‹ˆ์ง€๋งŒ ์–ด๋–ค ์ƒํ™ฉ์—์„œ๋Š” ์˜๋„์™€ ๋‹ค๋ฅด๊ฒŒ state๋ฅผ ์—…๋ฐ์ดํŠธ ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค.

์˜ˆ๋ฅผ ํ•œ๋ฒˆ ๋ณด์ž!

์˜ˆ์‹œ์—์„œ Counter์ด๋ผ๋Š” ์ปดํฌ๋„ŒํŠธ๋Š” count์™€ randomNum์ด๋ผ๋Š” state๋ฅผ ๋‘๊ฐœ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค.

๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด count๋Š” 1์”ฉ ์ฆ๊ฐ€ํ•˜๊ณ  ๋™์‹œ์— randomNum์—๋„ ๋žœ๋คํ•œ ์ƒˆ๋กœ์šด ์ˆซ์ž๊ฐ€ ๋“ค์–ด๊ฐ„๋‹ค.

์—ฌ๊ธฐ์„œ ์ฃผ์˜ ๊นŠ๊ฒŒ ๋ด์•ผํ•˜๋Š” ๊ฒƒ์€ handleClick์ด๋ผ๋Š” ํ•จ์ˆ˜์—์„œ setCount, setRandomNum์„ ๊ฐ™์ด ์ผ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

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

๋”ฐ๋ผ์„œ setํ•จ์ˆ˜๋ฅผ ๋‘๊ฐœ ์“ฐ๊ฒŒ ๋˜๋ฉด ๋ฆฌ๋ Œ๋”๋ง์ด ๋‘๋ฒˆ ์ผ์–ด๋‚  ๊ฒƒ์ด๋ผ๊ณ  ์˜ˆ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.

ํ•˜์ง€๋งŒ ๋ฆฌ์•กํŠธ๋Š” ๋˜‘๋˜‘ํ•˜๊ฒŒ๋„ batching์ด๋ผ๋Š” ๊ฒƒ์„ ์ด์šฉํ•ด์„œ ์—ฌ๋Ÿฌ๊ฐœ์˜ setState ํ•จ์ˆ˜๋ฅผ ํ•˜๋‚˜์˜ ๋ฆฌ๋ Œ๋”๋ง์œผ๋กœ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

๊ทธ๋ž˜์„œ console.log(โ€™renderโ€™)์„ ํ†ตํ•ด์„œ ๋ฆฌ๋ Œ๋”๋ง ํšŸ์ˆ˜๋ฅผ ๋ณด๋ฉด ๋ฒ„ํŠผ์ด ํด๋ฆญ๋  ๋•Œ๋งˆ๋‹ค ์ฝ˜์†”์ฐฝ์— render๊ฐ€ ํ•œ๋ฒˆ๋งŒ ์ฆ๊ฐ€ํ•˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

(๊ธฐ๋ณธ์ ์œผ๋กœ 2์”ฉ ์ฆ๊ฐ€ํ•˜๊ฒŒ ๋œ๋‹ค๋ฉด ๊ทธ๊ฒƒ์€ React.StrictMode๋กœ ์ธํ•ด ์ž๋™์œผ๋กœ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋”๋ธ” ๋ Œ๋”๋ง๋˜๋„๋ก ์„ค์ •๋˜์–ด์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ๋งŒ์•ฝ index.js์—์„œ React.StrictMode๋ฅผ ์ œ๊ฑฐํ•˜๊ฒŒ ๋˜๋ฉด ํ•œ๋ฒˆ์”ฉ ๋ฆฌ๋ Œ๋”๋ง ๋œ๋‹ค.)

import React, { useState } from "react";

const Counter = () => {
  const [count, setCount] = useState(0);
  const [randomNum, setRandomNum] = useState(0);

  const handleClick = () => {
    setCount(count + 1);
    setRandomNum(Math.floor(Math.random() * 10));
  };

  console.log('render')

  return (
    <div>
      <h2>Count : {count}</h2>
      <h2>Random Num : {randomNum}</h2>
      <button onClick={handleClick}>plus & new random</button>
    </div>
  );
};

export default Counter;

ํ•˜์ง€๋งŒ, ์‹ ๊ธฐํ•˜๊ฒŒ ์ด batching ๋•Œ๋ฌธ์— ์„œ๋กœ ๋‹ค๋ฅธ setํ•จ์ˆ˜์˜ ๊ฒฝ์šฐ state๊ฐ€ ์ž˜ ์—…๋ฐ์ดํŠธ ๋˜์ง€๋งŒ ๊ฐ™์€ setํ•จ์ˆ˜๋ฅผ ์—ฌ๋Ÿฌ๋ฒˆ ํ˜ธ์ถœํ•˜๋Š” ๊ฒฝ์šฐ์—๋Š” ์˜๋„ํ•œ ๋ฐ”์™€ ๋‹ค๋ฅด๊ฒŒ state๊ฐ€ ์—…๋ฐ์ดํŠธ๋˜์ง€ ์•Š๋Š” ํ˜„์ƒ์ด ์ƒ๊ธด๋‹ค.

์œ„์˜ ์˜ˆ์‹œ๋ฅผ ์กฐ๊ธˆ๋งŒ ๋ณ€ํ˜•ํ•ด๋ณด์ž.

๋‹ค์Œ๊ณผ ๊ฐ™์ด setCount๋ฅผ ํ•œ๋ฒˆ์ด ์•„๋‹Œ 3๋ฒˆ์„ ํ˜ธ์ถœํ•˜๊ณ  setRandomNum์„ ํ•œ๋ฒˆ ํ˜ธ์ถœํ•˜๋ฉด ์–ด๋–ค ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜ฌ์ง€ ํ•œ๋ฒˆ ์˜ˆ์ƒ์„ ํ•ด๋ณด์ž.

์›๋ž˜ ์˜๋„๋Œ€๋กœ๋ผ๋ฉด count๊ฐ€ 1์”ฉ์ด ์•„๋‹Œ 3์”ฉ ์ฆ๊ฐ€ํ•ด์•ผ ํ•œ๋‹ค. ํ•˜์ง€๋งŒ ๋ฒ„ํŠผ์„ ํด๋ฆญํ•ด ๋ณด๋ฉด 1์”ฉ ์ฆ๊ฐ€ํ•จ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

์ด๋Š” ์œ„์—์„œ ์„ค๋ช…ํ•œ batching ๋•Œ๋ฌธ์ด๋‹ค. batching์€ ์—ฌ๋Ÿฌ๊ฐœ์˜ setState ํ•จ์ˆ˜๋ฅผ ํ•˜๋‚˜๋กœ ๋ฌถ์–ด์„œ ๋ฆฌ๋ Œ๋”๋ง์„ ํ•œ๋ฒˆ๋งŒ ํ•œ๋‹ค๊ณ  ํ–ˆ๋‹ค.

๋”ฐ๋ผ์„œ setCount๊ฐ€ ์—ฌ๋Ÿฌ๋ฒˆ ํ˜ธ์ถœ๋˜์—ˆ๋‹ค๊ณ  ํ•ด๋„ ์ด๋ฅผ ๋ฌถ์–ด์„œ ๋ฆฌ๋ Œ๋”๋ง์ด ํ•œ๋ฒˆ๋งŒ ์ผ์–ด๋‚˜๋Š” ๊ฒƒ์ด๋‹ค.

๋ฆฌ๋ Œ๋”๋ง์ด ํ•œ๋ฒˆ๋งŒ ์ผ์–ด๋‚˜๊ธฐ ๋•Œ๋ฌธ์— 3๊ฐœ์˜ setCount์•ˆ์˜ count๊ฐ€ ๋ชจ๋‘ ๊ฐ™์€ ๊ฐ’์ด์—ฌ์„œ 1๋งŒ ์ฆ๊ฐ€๋˜๋Š” ๊ฒƒ์ด๋‹ค.

๊ทธ๋ ‡๋‹ค๋ฉด ์šฐ๋ฆฌ๊ฐ€ ์˜๋„ํ•œ ๋Œ€๋กœ count๊ฐ€ 3์”ฉ ์ฆ๊ฐ€ํ• ๋ ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผํ• ๊นŒ?

count+3์ด์–ด๋„ ๋˜์ง€๋งŒ setCount๋ฅผ ์ง€๊ธˆ์ฒ˜๋Ÿผ 3๋ฒˆ ์‚ฌ์šฉํ•ด๋„ ๋œ๋‹ค.

ํ•˜์ง€๋งŒ ์ด๋•Œ, count๋ฅผ ์“ฐ๋Š” ๊ฒƒ์ด ์•„๋‹Œ ์ฝœ๋ฐฑ์„ ์‚ฌ์šฉํ•ด์„œ prev ๊ฐ’์„ ์‚ฌ์šฉํ•ด์•ผํ•œ๋‹ค.

prev๋Š” setํ•จ์ˆ˜์—์„œ ์ œ๊ณตํ•˜๋Š” ์ด์ „๊ฐ’์ด๋‹ค. prev๋Š” ์ด์ „๊ฐ’์„ ์ €์žฅํ•˜๋Š” ์ž„์‹œ๊ณต๊ฐ„์ด๊ธฐ ๋•Œ๋ฌธ์— ๋ฆฌ๋ Œ๋”๋ง ์—†์ด๋„ ์—…๋ฐ์ดํŠธ๋œ ๊ฐ’์ด ์ €์žฅ๋œ๋‹ค.

import React, { useState } from "react";

const Counter = () => {
  const [count, setCount] = useState(0);
  const [randomNum, setRandomNum] = useState(0);

  const handleClick = () => {
    setCount(count + 1);
		setCount(count + 1);
		setCount(count + 1);
    setRandomNum(Math.floor(Math.random() * 10));
  };

  console.log('render')

  return (
    <div>
      <h2>Count : {count}</h2>
      <h2>Random Num : {randomNum}</h2>
      <button onClick={handleClick}>plus & new random</button>
    </div>
  );
};

export default Counter;

๋”ฐ๋ผ์„œ ์ฒ˜์Œ์— count+1 ์ด ๋˜์–ด 1์ด prev ๊ฐ’์œผ๋กœ ์ €์žฅ๋˜๋ฉฐ ๋‹ค์Œ setCount ํ•จ์ˆ˜์—์„œ ์ด prev๊ฐ’์„ ์ด์šฉํ•˜์—ฌ ๋‹ค์‹œ 1์„ ์ฆ๊ฐ€์‹œํ‚ด์œผ๋กœ์จ prev ๊ฐ’์ด 2๊ฐ€ ๋œ๋‹ค. ๋งจ๋งˆ์ง€๋ง‰ setCount์—์„œ prev๋Š” 2๊ฐ€ ๋˜๊ณ  ์ด๋ฅผ 1 ์ฆ๊ฐ€์‹œ์ผœ ์ตœ์ข…์ ์œผ๋กœ 3์ด ๋œ๋‹ค.

์ด๋ ‡๊ฒŒ prev ๊ฐ’์„ ์—…๋ฐ์ดํŠธ ํ•˜๋Š” ๊ฒฝ์šฐ์—๋Š” state๋ฅผ ์ง์ ‘์ ์œผ๋กœ ์‚ฌ์šฉํ•˜์—ฌ ๋ณ€๊ฒฝํ•˜๊ธฐ ๋ณด๋‹ค๋Š” prev๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

 const handleClick = () => {
    setCount(prev => prev + 1);          // 0 => 1
		setCount(prev => prev + 1);          // 1 => 2
		setCount(prev => prev + 1);          // 2 => 3
    setRandomNum(Math.floor(Math.random() * 10));
  };


๋ฐฐ์—ด / ๊ฐ์ฒด์—์„œ prev ์‚ฌ์šฉ๋ฒ•


๋ฐฐ์—ด์ด๋‚˜ ๊ฐ์ฒด์˜ ๊ฒฝ์šฐ ๋ฐ˜๋“œ์‹œ ๋ถˆ๋ณ€์„ฑ์„ ์ง€์ผœ์ค˜์•ผํ•œ๋‹ค.

๋”ฐ๋ผ์„œ ๋ฐฐ์—ด์˜ ๊ฒฝ์šฐ์—๋Š” push, splice, sort๊ณผ ๊ฐ™์ด ๋ฐฐ์—ด์„ ์ง์ ‘์ ์œผ๋กœ ๋ณ€๊ฒฝํ•˜๋Š” ๋ฉ”์†Œ๋“œ๋Š” ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค. ๋งŒ์•ฝ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์œผ๋ฉด ๊ธฐ์กด์˜ ๋ฐฐ์—ด์„ ๋ณต์‚ฌํ•ด์„œ ๋ณต์‚ฌํ•œ ๋ฐฐ์—ด์— ๋ฉ”์†Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.

๊ฐ์ฒด์˜ ๊ฒฝ์šฐ์—๋„ ๋ฐฐ์—ด๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๊ณ  ๋ถˆ๋ณ€์„ฑ์„ ์ง€์ผœ์ค˜์•ผ ํ•œ๋‹ค. ์ด๋•Œ ์ฃผ์˜ํ•  ๊ฒƒ์€ class component์˜ setํ•จ์ˆ˜๋Š” ๊ธฐ์กด์˜ object๋ฅผ spread operator๋กœ destructure ํ•˜์ง€ ์•Š์•„๋„ ์ž๋™์ ์œผ๋กœ ๊ธฐ์กด์˜ object์™€ ๋ณ€๊ฒฝ์‚ฌํ•ญ์„ ํ•ฉ์ณ์ฃผ์—ˆ๋‹ค. ํ•˜์ง€๋งŒ useState์˜ hook์€ ์ž๋™์ ์œผ๋กœ ์ด์ „ ๊ฐ์ฒด์™€ ํ˜„์žฌ ๊ฐ์ฒด๋ฅผ ํ•ฉ์ณ์ฃผ์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— spread operator๋กœ destructuring ํ•œ ํ›„์— ์ƒˆ๋กœ์šด value๋ฅผ key๋ฅผ ํ†ตํ•ด์„œ ์—…๋ฐ์ดํŠธ ํ•ด์ค˜์•ผํ•œ๋‹ค. ๋ฆฌ์•กํŠธ ๊ณต์‹๋ฌธ์„œ์— ๋ณด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์จ์ ธ์žˆ๋‹ค.

๐Ÿ’ก < **์ฃผ์˜ >**

ํด๋ž˜์Šค ์ปดํฌ๋„ŒํŠธ์˜ย setStateย ๋ฉ”์„œ๋“œ์™€๋Š” ๋‹ค๋ฅด๊ฒŒ,ย useState๋Š” ๊ฐฑ์‹  ๊ฐ์ฒด(update objects)๋ฅผ ์ž๋™์œผ๋กœ ํ•ฉ์น˜์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค. ํ•จ์ˆ˜ ์—…๋ฐ์ดํ„ฐ ํผ์„ ๊ฐ์ฒด ์ „๊ฐœ ์—ฐ์‚ฐ์ž์™€ ๊ฒฐํ•ฉํ•จ์œผ๋กœ์จ ์ด ๋™์ž‘์„ ๋ณต์ œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

const [state, setState] = useState({});
setState(prevState => {
  // Object.assign would also work
  return {...prevState, ...updatedValues};
});

๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์œผ๋กœ๋Š”ย useReducer๊ฐ€ ์žˆ๋Š”๋ฐ ์ด๋Š” ์—ฌ๋Ÿฌ๊ฐœ์˜ ํ•˜์œ—๊ฐ’๋“ค์„ ํฌํ•จํ•œ state ๊ฐ์ฒด๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ๋ฐ์— ๋” ์ ํ•ฉํ•ฉ๋‹ˆ๋‹ค.

์ฃผ๋กœ, ์ด๋ฅผ ์œ„ํ•ด์„œ spread operator๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

spread operator๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

// ๊ฐ์ฒด์—์„œ ํ•˜์ง€ ๋ง์•„์•ผํ•  ๊ฒƒ : ๋ณ€๊ฒฝํ•  key:value ๊ฐ’๋งŒ ๋„ฃ๋Š” ๊ฒƒ
setState({name:value})

// ๊ฐ์ฒด์˜ ๊ฒฝ์šฐ
setState(prev => {
	return {
		...prev,
		[name] : value
	}
}

// ๋ฐฐ์—ด์˜ ๊ฒฝ์šฐ
setState(prev => [...prev, newValue])

๋‹ค์Œ์˜ ์˜ˆ์‹œ๋Š” ์ด๋ฆ„, ์ด๋ฉ”์ผ, ๋‚˜์ด๋ฅผ ์ž…๋ ฅํ•˜๋Š” UserInfo ๋ถ€๋ถ„๊ณผ tag๋“ค์„ ์ž…๋ ฅํ•˜๋Š” AddTag ๋ถ€๋ถ„์ด ์žˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ๊ทธ ์•„๋ž˜์— ์ด๊ฒƒ์„ ์ถœ๋ ฅํ•˜๋Š” ๋ถ€๋ถ„์ด ์žˆ๋‹ค.

input์˜ ๊ฐ’์„ ๊ด€๋ฆฌํ•˜๋Š” userInfo state๊ฐ€ ํ•˜๋‚˜์žˆ๊ณ  ์ž…๋ ฅํ•˜๊ณ  ์žˆ๋Š” currentTag state ํ•œ๊ฐœ์™€, tag๋“ค์„ ์ „์ฒด ๊ด€๋ฆฌํ•˜๋Š” tags๋ผ๋Š” state ํ•˜๋‚˜๊ฐ€ ์žˆ๋‹ค.

userInfo์™€ ๊ฐ™์€ ๊ฐ์ฒด๋Š” setState๋ฅผ ์ด์šฉํ•ด์„œ value๊ฐ’์„ ์—…๋ฐ์ดํŠธํ•  ๋•Œ key๊ฐ€ ๋™์ ์ด๋ฏ€๋กœ [key] ํ˜•์‹์œผ๋กœ ์ž‘์„ฑ์„ ํ•ด์•ผํ•œ๋‹ค.

import React, { useState } from "react";

const User = () => {
  const [userInfo, setUserInfo] = useState({
    email: "",
    name: "",
    age: 0
  });
  const [currentTag, setCurrentTag] = useState("");
  const [tags, setTags] = useState([]);

  const handleUserInfoChange = (e) => {
    const { name, value } = e.target;
    setUserInfo((prev) => {
      return {
        ...userInfo,
        [name]: value
      };
    });
  };

  const handleTagChange = (e) => {
    setCurrentTag(e.target.value);
  };

  const handleSubmit = (e) => {
    e.preventDefault();
    setTags((prev) => [...prev, currentTag]);
    setCurrentTag("");
  };

  console.log("render");

  return (
    <div>
      <h2>User Info</h2>
      <input
        type="text"
        name="name"
        value={userInfo["name"]}
        placeholder="์ด๋ฆ„"
        onChange={handleUserInfoChange}
      />
      <input
        type="text"
        name="email"
        value={userInfo["email"]}
        placeholder="์ด๋ฉ”์ผ"
        onChange={handleUserInfoChange}
      />
      <input
        type="number"
        name="age"
        value={userInfo["age"]}
        placeholder="๋‚˜์ด"
        onChange={handleUserInfoChange}
      />

      <form onSubmit={handleSubmit}>
        <h2>Add Tag</h2>
        <input
          type="text"
          name="tags"
          value={currentTag}
          onChange={handleTagChange}
        />
        <button type="button">์ œ์ถœ</button>
      </form>

      <h2>Print User & Tag</h2>
      <h3>-User</h3>
      {Object.keys(userInfo).map((key) => (
        <p key={key}>
          {key} : {userInfo[key]}
        </p>
      ))}
      <h3>-Tag</h3>
      {tags.map((tag, idx) => (
        <p key={idx}>{tag}</p>
      ))}
    </div>
  );
};

export default User;
profile
code for a change

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

comment-user-thumbnail
2023๋…„ 11์›” 14์ผ

์ •๋ง ๊ผผ๊ผผํ•˜๊ฒŒ ์ •๋ฆฌํ•ด์ฃผ์…จ๋„ค์š” ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค :)

๋‹ต๊ธ€ ๋‹ฌ๊ธฐ