Skip to content

Latest commit

ย 

History

History

adding-interactivity

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
ย 
ย 

Adding Interactivity

Note

'Adding Interactivity' ์ฑ•ํ„ฐ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋‚ด์šฉ์„ ๋‹ค๋ฃน๋‹ˆ๋‹ค.

  • ์‚ฌ์šฉ์ž์˜ ์ด๋ฒคํŠธ์— ์‘๋‹ตํ•˜๋Š” ๋ฐฉ๋ฒ•
  • ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ •๋ณด๋ฅผ ๊ธฐ์–ตํ•˜๊ฒŒ ํ•˜๋Š” ๋ฐฉ๋ฒ•
  • UI๋ฅผ ํ™”๋ฉด์— ํ‘œ์‹œํ•˜๋Š” ๋‘ ๊ฐ€์ง€ ๋‹จ๊ณ„
  • ์Šค๋ƒ…์ƒท์ฒ˜๋Ÿผ ๋™์ž‘ํ•˜๋Š” ์ƒํƒœ
  • ์ƒํƒœ ์—…๋ฐ์ดํŠธ๋ฅผ ํ์— ์ถ”๊ฐ€ํ•˜๋Š” ๋ฐฉ๋ฒ•
  • ๊ฐ์ฒด ์ƒํƒœ๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๋Š” ๋ฐฉ๋ฒ•
  • ๋ฐฐ์—ด ์ƒํƒœ๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๋Š” ๋ฐฉ๋ฒ•

Adding Interactivity

  1. Unlike regular JavaScript variables, React state behaves more like a snapshot. Setting it does not change the state variable you already have, but instead triggers a re-render. This can be surprising at first!

    • ๋ฒ„๊ทธ๋ฅผ ๋งŽ์ด ๊ฒช์—ˆ๋˜ ๋ถ€๋ถ„์ด๋ผ ๊ณต๊ฐ๋œ๋‹ค.
  2. replacing setScore(score + 1) with setScore(s => s + 1)

    • ๋‘ ๋ฐฉ์‹์˜ ์ฐจ์ด๋ฅผ ๋ช…ํ™•ํ•˜๊ฒŒ ๋ชฐ๋ž๋Š”๋ฐ ์ด๋ฒˆ์— ์•Œ๊ฒŒ ๋˜์—ˆ๋‹ค. ๋‘๋ฒˆ์งธ ๋ฐฉ์‹์œผ๋กœ ์‚ฌ์šฉํ•  ๋•Œ์— ๋ฒ„๊ทธ๋ฅผ ํ”ผํ•  ์ˆ˜ ์žˆ์–ด ๊ถŒ์žฅ๋˜์—ˆ๋‹ค.
  3. Immer?
    • ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ž์ฒด๋Š” ์œ ์šฉํ•ด๋ณด์ด์ง€๋งŒ ์ฝ”๋“œ๋ฅผ ํš๊ธฐ์ ์œผ๋กœ ์ค„์—ฌ์ฃผ์ง€๋Š” ์•Š๋Š” ๋“ฏ ๋ณด์ธ๋‹ค. ์ฃผ๋ณ€์—์„œ ์‚ฌ์šฉํ•˜๋Š” ์ผ€์ด์Šค๋ฅผ ๋ณด์ง€ ๋ชปํ•จ
    • ์ด์ œ ๋ธŒ๋ผ์šฐ์ €์—์„œ ๊ฐ์ฒด ๊นŠ์€ ๋ณต์‚ฌ๋ฅผ ์ˆ˜ํ–‰ํ•ด์ฃผ๋Š” structuredClone()๋ฅผ ์ œ๊ณตํ•ด์ฃผ๋‹ˆ ์‚ฌ์šฉํ•  ์ด์œ ๊ฐ€ ๋”ฑํžˆ ์—†์ง€ ์•Š์„๊นŒ

Responding to Events

  1. By convention, it is common to name event handlers as handle followed by the event name. Youโ€™ll often see onClick={handleClick}, onMouseEnter={handleMouseEnter}, and so on.

    • ์ปจ๋ฒค์…˜ ๊ด€๋ จ๋œ ๋‚ด์šฉ์ด ๋‹ค์ˆ˜ ๋ณด์—ฌ ํ•จ์ˆ˜ ๊ด€๋ จํ•˜์—ฌ convention์„ ์ •ํ•  ๋•Œ์— react docs๋ฅผ ๋ ˆํผ๋Ÿฐ์Šค ์‚ผ์„ ์ˆ˜ ์žˆ์„ ๊ฒƒ ๊ฐ™๋‹ค.
  2. In the second example, the () at the end of handleClick() fires the function immediately during rendering, without any clicks. This is because JavaScript inside the JSX { and } executes right away. If you want to define your event handler inline, wrap it in an anonymous function like so:

    • ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ์—์„œ ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•˜๋Š”๊ฑธ ์ง€์–‘ํ•ด์•ผ ํ•œ๋‹จ ๊ฑธ ๋ฌด์ง€์„ฑ์œผ๋กœ ์•Œ๊ณ  ์žˆ์—ˆ๋Š”๋ฐ, docs์— ๋ช…ํ™•ํ•˜๊ฒŒ ์žˆ์œผ๋‹ˆ ์ด์œ ๋ฅผ ํ™•์‹คํžˆ ์•Œ ์ˆ˜ ์žˆ์—ˆ๋‹ค.
  3. By convention, event handler props should start with on, followed by a capital letter.

    • handle, on์ด ํ˜ผํ•ฉ๋˜์–ด ์‚ฌ์šฉ๋˜๊ณ  ๋ฐฉ๋Œ€ํ•œ๋ฐ ๊ทœ์น™์ด ์—†์—ˆ๊ณ  ๋ฆฌํŒฉํ† ๋ง ์‹œ์—๋„ ๊ธฐ์ค€์ด ์—†์—ˆ๋Š”๋ฐ docs์—์„œ ๋ช…ํ™•ํ•˜๊ฒŒ ๊ตฌ๋ถ„ํ•˜์—ฌ ์„ค๋ช…ํ•ด์ฃผ๋‹ˆ๊นŒ ํ˜„์‹ค์ ์œผ๋กœ ๋„์›€์ด ๋งŽ์ด ๋๋‹ค.
  4. We say that an event โ€œbubblesโ€ or โ€œpropagatesโ€ up the tree: it starts with where the event happened, and then goes up the tree.

    • ๋ฉด์ ‘์—์„œ ํ•ด๋‹น ์งˆ๋ฌธ์„ ๋งŽ์ด ๋ฐ›์€ ๊ฒƒ ๊ฐ™๋‹ค. (์ด๋ฒคํŠธ ๋ฒ„๋ธ”๋ง์„ ์„ค๋ช…ํ•˜๋ผ, ์ด๋ฅผ ์–ด๋–ป๊ฒŒ ์ฒ˜๋ฆฌํ–ˆ๋Š”์ง€๋ฅผ ์„ค๋ช…ํ•˜๋ผ)
  5. All events propagate in React except onScroll, which only works on the JSX tag you attach it to.

    • ํ•œ๊ธ€ ๋ฒˆ์—ญ์ด ์กฐ๊ธˆ ์ด์ƒํ•œ ๋А๋‚Œ...
    • on์œผ๋กœ ์‹œ์ž‘ํ•˜๋Š” ์ด๋ฒคํŠธ๊ฐ€ ๋งŽ์€๋ฐ, onClick, onChange ๋“ฑ๋งŒ ์ œํ•œ์ ์œผ๋กœ ์“ฐ๋Š”๊ฒƒ ๊ฐ™์•„์„œ ์•„์‰ฝ๋‹ค.
    • onScroll, onDrop ๊ณผ ๊ฐ™์€ ์ด๋ฒคํŠธ๋Š” ์˜ˆ์™ธ์ผ€์ด์Šค ๊ฐœ๋ฐœ ์‹œ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๋Š” ๋“ฏ
  6. By convention, itโ€™s usually called e, which stands for โ€œeventโ€.

    • ๊ทธ๋™์•ˆ event๋‚˜ error๋‚˜ ๋ชจ๋‘ ํ’€๋„ค์ž„์„ ์ ์—ˆ๋Š”๋ฐ docs์—์„œ e๋กœ ์ถ•์•ฝํ•ด์„œ ์‚ฌ์šฉํ•˜๋Š” ๋‚ด์šฉ์„ ์ ์—ˆ๋‹ค.
    • ๋‹ค๋“ค e๋กœ ์ถ•์•ฝํ•˜์—ฌ ์“ฐ๋Š” ๊ฑธ ์„ ํ˜ธํ•˜๋Š” ํŽธ!
  7. e.stopPropagation ์‚ฌ์šฉ ์‚ฌ๋ก€ ๊ณต์œ 
    • ํฐ div์— card๊ฐ€ 4๊ฐœ ์žˆ๊ณ , card ๋‚ด๋ถ€์˜ ์ด๋ฏธ์ง€์— ํด๋ฆญ ์ด๋ฒคํŠธ๊ฐ€ ์žˆ๊ณ  ๊ฐ๊ฐ์˜ card์—๋„ ํด๋ฆญ ์ด๋ฒคํŠธ๊ฐ€ ์žˆ๋Š” ํ˜•ํƒœ
    • ์ด๋ฏธ์ง€ ํด๋ฆญ ์ด๋ฒคํŠธ์— e.stopPropagation์„ ์‚ฌ์šฉํ–ˆ์—ˆ๋‹ค
     <div>
         <Card onClick={} />
         <Card onClick={} />
         <Card onClick={} />
         <Card onClick={} />
     </div>
  8. In rare cases, you might need to catch all events on child elements, even if they stopped propagation. For example, maybe you want to log every click to analytics, regardless of the propagation logic. You can do this by adding Capture at the end of the event name:

    • Capture๊ฐ€ ๋ถ™์€ ์ด๋ฒคํŠธ๊ฐ€ ์–ด๋–ค ์šฉ๋„์ธ์ง€ ๋ชฐ๋ž๋Š”๋ฐ, ๋ถ„์„ ๋„๊ตฌ ์‚ฌ์šฉํ•  ๋•Œ์— ์œ ์šฉํ•  ๊ฒƒ ๊ฐ™๋‹ค!

๐Ÿคทโ€โ™€๏ธ ์งˆ๋ฌธ

  • Q: ํšŒ์‚ฌ์—์„œ ์ ‘๊ทผ์„ฑ ์–ด๋–ป๊ฒŒ ์ฑ™๊ธฐ๋Š”์ง€?
  • A:
  • Q: ํšŒ์‚ฌ์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๋ถ„์„ ๋„๊ตฌ?
  • A:
    • ๋ณดํ†ต์€ GA ์‚ฌ์šฉ, vercel analytics ์ œ์•ˆ ๋ฐ›์•˜์œผ๋‚˜ ๊ธˆ์•ก ๋ถ€๋‹ด์œผ๋กœ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Œ. (tagmanager์—์„œ ์…‹ํŒ…ํ•˜๋˜ ๊ฑธ ์•Œ์•„์„œ ํ•ด์ฃผ๋Š” ์ด์ ์ด ์žˆ๋Š” ๋“ฏ)
    • GA ๋ถ„์„์— ๋Œ€ํ•œ ์ฑ…์ž„์†Œ์žฌ๊ฐ€ ๋ช…ํ™•ํ•˜์ง€ ์•Š์•„์„œ ํ˜ผ๋ž€์Šค๋Ÿฝ๊ธฐ๋„ ํ•˜๋‹ค. (๊ฐœ๋ฐœ์ธก์—์„œ ๊ด€๋ฆฌํ•ด์•ผ ํ•˜๋Š”์ง€ ๋งˆ์ผ€ํŒ… ์ธก์—์„œ ๊ด€๋ฆฌ ํ•ด์•ผ ํ•˜๋Š”์ง€?)
    • ๋งˆ์ผ€ํŒ… ํŒŒํŠธ์—์„œ GA๋ฅผ ๋‹ค๋ฃจ๊ธฐ ์–ด๋ ค์›Œ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค๋ฃจ๋Š” ๊ฐœ๋ฐœ์ž๋ฅผ ๋”ฐ๋กœ ํ•„์š”๋กœ ํ•˜๊ธฐ๋„ ํ•œ๋‹ค.

State: A Component's Memory

    1. Aย state variableย to retain the data between renders. 2. Aย state setter functionย to update the variable and trigger React to render the component again.
    • ๊ด€์Šต์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๋˜ useState๋ฅผ 2depth๋กœ ๋‚˜๋ˆ„์–ด์„œ ๋ณด์—ฌ์ฃผ๋Š”๊ฒŒ ์ธ์ƒ ๊นŠ์—ˆ๋‹ค.
  1. Hooksโ€”functions starting with use โ€”can only be called at the top level of your components or your own Hooks.

    • ์ปค์Šคํ…€ํ›…์ด ํ•„์ˆ˜์ ์ด๋ผ๊ณค ์ƒ๊ฐ์„ ์•ˆํ–ˆ๋Š”๋ฐ (๋ฆฌํŒฉํ† ๋ง์˜ ์ผ์ข…์œผ๋กœ ์—ฌ๊น€) ๋ญ”๊ฐ€ docs์—์„œ ์ปค์Šคํ…€ํ›…์„ ์ ๊ทน์ ์œผ๋กœ ์–ธ๊ธ‰ ํ•˜๋Š”๊ฒƒ ๊ฐ™์•„์„œ ์žฌ๋ฐŒ๋‹ค.
    • toss์˜ slash๋ผ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ๋„ ์ปค์Šคํ…€ํ›…์„ ๊ณตํ†ต์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์—ฌ์ง€๋ฅผ ์ œ๊ณตํ•ด์ฃผ์–ด ์ž˜ ์“ฐ๋ฉด ์œ ์šฉํ•  ๊ฒƒ ๊ฐ™๋‹ค.
    1. Your component renders the first time.ย Because you passedย 0ย toย useStateย as the initial value forย index, it will returnย [0, setIndex]. React remembersย 0ย is the latest state value. 2. You update the state.ย When a user clicks the button, it callsย setIndex(index + 1).ย indexย isย 0, so itโ€™sย setIndex(1). This tells React to rememberย indexย isย 1ย now and triggers another render. 3. Your componentโ€™s second render.ย React still seesย useState(0), but because Reactย remembersย that you setย indexย toย 1, it returnsย [1, setIndex]ย instead. Instead, to enable their concise syntax, Hooks rely on a stable call order on every render of the same component. This works well in practice because if you follow the rule above (โ€œonly call Hooks at the top levelโ€), Hooks will always be called in the same order. Additionally, a linter plugin catches most mistakes. Internally, React holds an array of state pairs for every component. It also maintains the current pair index, which is set to 0 before rendering. Each time you call useState, React gives you the next state pair and increments the index. You can read more about this mechanism in React Hooks: Not Magic, Just Arrays.
    • ๋”ฑํžˆ ์˜๋ฌธ์„ ๊ฐ€์ง€๊ณ  ์žˆ์ง€ ์•Š์•˜๋Š”๋ฐ ์ฒ˜์Œ ์•Œ๊ฒŒ ๋œ ๋ถ€๋ถ„. ๋ Œ๋”๋ง ์‹œ ๋ฐฐ์—ด ๊ธฐ๋ฐ˜์˜ ํ˜ธ์ถœ ์ˆœ์„œ๋กœ ๋ Œ๋”๋งํ•œ๋‹ค๋Š” ๋ถ€๋ถ„์ด ์ธ์ƒ๊นŠ์—ˆ๋‹ค.
    • ์ด๋Ÿฐ ์ง€์‹์˜ ์ฐจ์ด๊ฐ€ ๋ ˆ๋ฒจ ์ฐจ์ด๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ ๊ฐ™๋‹คโ€ฆ!
  2. How does React know which state to return?

    • ์ฒ˜์Œ์— ์ œ๋ชฉ์ด ๋ญ๊ฐ€ ๋ฌธ์ œ์ธ์ง€ ํŒŒ์•…์„ ๋ชปํ–ˆ๋Š”๋ฐ, ์ฝ์–ด๋ณด๋‹ˆ ์ „ํ˜€ ์ƒ๊ฐ์น˜๋„ ๋ชปํ•œ ๋ถ€๋ถ„์ด์–ด์„œ ์ธ์ƒ ๊นŠ์—ˆ๋‹ค.
    • React hooks: not magic, just arrays ๊ธ€์˜ ์ด๋ฏธ์ง€์™€ ํ•จ๊ป˜ ๋ณด๋ฉด ์ดํ•ด๊ฐ€ ์‰ฝ๋‹ค.
    • ์˜ˆ์ œ ์ฝ”๋“œ๋ฅผ ๋ณด๋ฉฐ ์ƒ์ˆ˜์— ํ•ด๋‹นํ•˜๋Š” ์˜์—ญ์€ ์ฝ”๋“œ ๋‚ด๋ถ€์˜ ํ•˜๋‹จ๋ถ€์— ์œ„์น˜์‹œํ‚ค๋Š” ๊ฒƒ๋„ ๊น”๋”ํ•˜๋‹ค๋Š” ์ƒ๊ฐ์ด ๋“ค์—ˆ๋‹ค.
  3. Unlike props, state is fully private to the component declaring it. The parent component canโ€™t change it.

    • ์บก์Аํ™”๊ฐ€ ์ƒ๊ฐ๋‚œ๋‹ค.
    • ์˜์—ญ์— ์ƒ๊ด€์—†์ด ์ž˜ ์งœ์ธ ์ฝ”๋“œ์˜ ์›๋ฆฌ๋Š” ๋น„์Šทํ•˜๋‹ค

Render and Commit

    1. Triggeringย a render (delivering the guestโ€™s order to the kitchen) 2. Renderingย the component (preparing the order in the kitchen) 3. Committingย to the DOM (placing the order on the table)
    • state ์ƒํƒœ๋ฅผ DOM์— ๋ฐ˜์˜ํ•˜๋Š” ๋กœ์ง์˜ ํ•ต์‹ฌ
    • ์ด ๋‹จ๊ณ„์™€ Real dom์— ๊ทธ๋ ค์ง€๋Š” painting ๋‹จ๊ณ„๋ฅผ ๊ตฌ๋ถ„ํ•˜๋Š”๊ฒŒ ์ธ์ƒ ๊นŠ์—ˆ๋‹ค. (virtual dom)
  1. โ€œRenderingโ€ is React calling your components.

    • ๋ Œ๋”๋ง์„ ํ•œ ๋งˆ๋””๋กœ ํ‘œํ˜„ํ•˜๋ฉด ์ปดํฌ๋„ŒํŠธ ํ˜ธ์ถœ
    • ์ปดํฌ๋„ŒํŠธ๋„ ๊ฒฐ๊ตญ ํ•จ์ˆ˜๋‹ˆ๊นŒ ์ด ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœ -> ์–˜๊ฐ€ jsx ๋ฆฌํ„ด -> ํ™”๋ฉด์— ๋ณด์—ฌ์ง ์š” ๊ณผ์ • ๋•Œ๋ฌธ์— '๋ Œ๋”๋ง' ์ด๋ผ๊ณ  ํ•œ ๋‹จ์–ด๋กœ ๋งํ•˜๋Š” ๊ฑด๊ฐ€ ์‹ถ๊ธฐ๋„
    • ๊ฒฐ๊ตญ jsx๋„ js๋กœ ๋งŒ๋“ค์–ด์ง„ ํ•จ์ˆ˜...
  2. This process is recursive: if the updated component returns some other component, React will render that component next, and if that component also returns something, it will render that component next, and so on.

    • ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ Œ๋”๋ง๋˜๋ฉด ์ž์‹ ์ปดํฌ๋„ŒํŠธ๋„ ๋ Œ๋”๋ง๋œ๋‹ค๋Š” ๊ฑด ์•Œ๊ณ  ์žˆ์—ˆ๋Š”๋ฐ ๊ทธ ์ด์œ ๊ฐ€ ์žฌ๊ท€์ ์œผ๋กœ ํ˜ธ์ถœ๋˜๊ธฐ ๋•Œ๋ฌธ์ด๋ผ๋Š” ๊ฑด ๋ชฐ๋ž๋‹ค.
  3. React only changes the DOM nodes if thereโ€™s a difference between renders. For example, here is a component that re-renders with different props passed from its parent every second. Notice how you can add some text into the <input>, updating its value, but the text doesnโ€™t disappear when the component re-renders:

    • controlled component๊ฐ€ ์ž˜๋ชป ์‚ฌ์šฉํ•˜๋ฉด ์ œํ’ˆ์— ๋ถ€ํ•˜๋ฅผ ์ผ์œผํ‚ฌ ์ˆ˜ ์žˆ๋Š” ์›์ธ์ด๋ผ ๋ฆฌ๋งˆ์ธ๋“œ ํ•  ์ˆ˜ ์žˆ์–ด ์ข‹์•˜๋‹ค.
    • ๋ฒˆ๊ฑฐ๋กœ์›Œ๋„ Form library๊ฐ™์€๊ฑธ ๋ถ™์—ฌ์„œ ๊ฐ’์„ ์ฒ˜๋ฆฌํ•ด์•ผ๊ฒ ๋‹ค. (react-hook-form์„ ์ฃผ๋กœ ์‚ฌ์šฉ)
    • ์ตœ๊ทผ react-hook-form๊ณผ ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋Š”๋ฐ, reset ํ•จ์ˆ˜ ๊ด€๋ จํ•˜์—ฌ ๋™์ž‘์ด ์ œ๋Œ€๋กœ ๋˜์ง€ ์•Š์•„ ํž˜๋“ค์—ˆ๋‹ค. react-hook-form์„ ์‚ฌ์šฉํ•˜๋ฉด ๊นŒ๋‹ค๋กœ์šด ์š”๊ตฌ์‚ฌํ•ญ์ด์–ด๋„ ํ•ด๊ฒฐ ๊ฐ€๋Šฅํ•˜๊ธด ํ•˜๋‚˜ docs๊ฐ€ ์นœ์ ˆํ•˜์ง€ ์•Š์•„ ๊ฐ€๋” ์ด๋ ‡๊ฒŒ ์• ๋ฅผ ๋จน๊ธฐ๋„...
    • MUI์™€ ๊ฐ™์€ ์™ธ๋ถ€๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ์—” controller์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋Š” ํŽธ
    • Q: ํผ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ ๊ฐ€ ๋ฌด์—‡์ผ๊นŒ์š”?
      • ์ž…๋ ฅ ์นธ์ด ์—ฌ๋Ÿฌ๊ฐœ์ผ ๋•Œ, ๋ชจ๋“  ๋ถ„๊ธฐ์™€ ์ผ€์ด์Šค๋ฅผ ๊ณ ๋ คํ•ด์„œ ์น˜๋‹ค๋ณด๋ฉด state์˜ ์–‘์ด ๋„ˆ๋ฌด ์ปค์ง€๊ณ , ํ•ธ๋“ค๋Ÿฌ์˜ ์–‘์ด ๋„ˆ๋ฌด ๋งŽ์•„์ง
      • customHook์„ ์ง์ ‘ ์งœ๋Š” ๊ฒƒ๋ณด๋‹ค ๊ณต์ˆ˜๊ฐ€ ์ ๊ฒŒ ๋“ ๋‹ค.
      • ํผ์ด ๋‹ค๋ฅธ ํผ์— ์˜ํ–ฅ์„ ๋ฐ›๋Š” ์‹์ด๋ฉด ๋ณต์žก๋„๊ฐ€ ์˜ฌ๋ผ๊ฐ€๋Š”๋ฐ ํผ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์‚ฌ์šฉ ์‹œ์—” ํ›จ์”ฌ ํŽธํ•˜๊ฒŒ ์ž‘์„ฑ ๊ฐ€๋Šฅํ•˜๋‹ค.
      • ์œ ํšจ์„ฑ ๊ฒ€์ฆ๋„ ํ›จ์”ฌ ์ž‘์„ฑํ•˜๊ธฐ๊ฐ€ ์‰ฝ๋‹ค. (customํ•œ validation๋„ ๊ฐ€๋Šฅ) โ†’ ์ดํ›„์˜ ๋™์ž‘์„ formState๋กœ ๊ด€๋ฆฌํ•˜๋Š”๋ฐ ์ด ์ ์ด ์œ ์šฉ

๐Ÿคทโ€โ™€๏ธ ์งˆ๋ฌธ

  • Q: ํšŒ์‚ฌ์—์„œ ์„ฑ๋Šฅ ์ตœ์ ํ™” ์–ด๋–ป๊ฒŒ ์ฑ™๊ธฐ๋Š”์ง€?
  • A: ๊ฐœ์ธ ์—ญ๋Ÿ‰์— ๋‹ฌ๋ฆฐ ๋А๋‚Œ... ๊ฐœ๋ฐœ์ž๊ฐ€ ์ตœ์ ํ™” ํ–ˆ๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ํšŒ์‚ฌ์—์„  ์‹ ๊ฒฝ์จ์ฃผ์ง€ ๋ชปํ•˜๋Š” ๋А๋‚Œ์ด๋‹ค. (ํ•„์ˆ˜์ ์ธ ์˜์—ญ์ด๋ผ๊ณ  ์ƒ๊ฐ์„ ๋ชปํ•˜๋Š” ๋“ฏ)
  • Q: ํ…Œ์ด๋ธ” ํ‘œํ˜„ ์‹œ ๋ณด์ด์ง€ ์•Š๋Š” ๋ถ€๋ถ„ ๋ Œ๋”๋ง ๋˜์ง€ ์•Š๋„๋ก ํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ?
  • A:

๐Ÿ’ก ์ •๋ณด

react-hook-form์˜ useFieldArray ์‚ฌ์šฉ ์‚ฌ๋ก€

State as a Snapshot

  1. ์‚ฌ์ง„์ด๋‚˜ ๋™์˜์ƒ ํ”„๋ ˆ์ž„๊ณผ ๋‹ฌ๋ฆฌ ๋ฐ˜ํ™˜ํ•˜๋Š” UI โ€œ์Šค๋ƒ…์ƒทโ€์€ ๋Œ€ํ™”ํ˜•์ž…๋‹ˆ๋‹ค.

    • ์—ญ์‹œ ์‚ฌ์šฉ์ž์™€์˜ ์ธํ„ฐ๋ž™์…˜์„ ์ฑ…์ž„์ง€๋Š” ํŒŒํŠธ๋ผ๋Š” ๊ฒŒ ํ”„๋ก ํŠธ์—”๋“œ์˜ ๋ฌ˜๋ฏธ๋ผ๊ณ  ์ƒ๊ฐ
    • ์‚ฌ์šฉ์ž์™€ ๊ฐ€์žฅ ๋งž๋‹ฟ์•„ ์žˆ๋Š” ์ง๋ฌด
    • ์œ ์ €์— ๋Œ€ํ•œ ์‹ ๋ขฐ๋ฅผ ์žƒ์–ด๊ฐ€๊ณ  ์žˆ์–ด์š”. ใ…‹ใ…‹ ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ๋™์ž‘๊ณผ ์ž…๋ ฅ๋“ค
  2. React๊ฐ€ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋‹ค์‹œ ๋ Œ๋”๋งํ•  ๋•Œ,

    1. React๊ฐ€ ํ•จ์ˆ˜๋ฅผ ๋‹ค์‹œ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.
    2. ํ•จ์ˆ˜๊ฐ€ ์ƒˆ๋กœ์šด JSX ์Šค๋ƒ…์ƒท์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
    3. ๊ทธ๋Ÿฌ๋ฉด React๊ฐ€ ๋ฐ˜ํ™˜ํ•œ ์Šค๋ƒ…์ƒท๊ณผ ์ผ์น˜ํ•˜๋„๋ก ํ™”๋ฉด์„ ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค.
    • ์ง๊ด€์ ์œผ๋กœ๋Š” ์ดํ•ด๊ฐ€ ๋˜์ง€๋งŒ, ์ •ํ™•ํ•˜๊ฒŒ ๋ฌด์Šจ ํ”„๋กœ์„ธ์Šค์ธ์ง€ ์ดํ•ด๊ฐ€ ๋˜์ง€๋Š” ์•Š๋„ค์š”. ์—ฌ๋Ÿฌ๋ฒˆ ์ฝ์œผ๋ฉฐ ์ƒ๊ฐํ•ด๋ด์•ผ๊ฒ ์–ด์š”.
  3. ์ปดํฌ๋„ŒํŠธ์˜ ๋ฉ”๋ชจ๋ฆฌ๋กœ์จ state๋Š” ํ•จ์ˆ˜๊ฐ€ ๋ฐ˜ํ™˜๋œ ํ›„ ์‚ฌ๋ผ์ง€๋Š” ์ผ๋ฐ˜ ๋ณ€์ˆ˜์™€ ๋‹ค๋ฆ…๋‹ˆ๋‹ค. state๋Š” ์‹ค์ œ๋กœ ํ•จ์ˆ˜ ์™ธ๋ถ€์— ๋งˆ์น˜ ์„ ๋ฐ˜์— ์žˆ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ React ์ž์ฒด์— "์กด์žฌโ€ํ•ฉ๋‹ˆ๋‹ค.

    state snapshot 1state snapshot 2state snapshot 3
    • ์ƒํƒœ๋ฅผ ์ปดํฌ๋„ŒํŠธ ๋‚ด์— ์ •์˜ํ•˜๋‹ค ๋ณด๋‹ˆ๊นŒ ์ปดํฌ๋„ŒํŠธ์— ์ข…์†๋œ๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ๋Š”๋ฐ React๊ฐ€ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค๋Š” ๊ฒƒ์ด ๋” ๋ง์ด ๋˜๋„ค์š”.
    • ๊ทธ๋ฆผ์ด ์—†์—ˆ์œผ๋ฉด React๊ฐ€ ์ž๊ธฐ ์„ ๋ฐ˜์— ์ƒํƒœ๋ฅผ ๊ฐ–๊ณ  ์žˆ๋‹ค๋Š” ๊ฑธ ์ดํ•ดํ•˜๊ธฐ ์–ด๋ ค์› ์„ ๊ฒƒ ๊ฐ™๋‹ค.
    • ๋‹ค๋ฅธ ๊ณต์‹ ๋ฌธ์„œ๋Š” ์ด๋ ‡๊ฒŒ ์ผ๋Ÿฌ์ŠคํŠธ๊นŒ์ง€ ๋งŒ๋“ค๋ฉด์„œ ๊ณต๋“ค์ด๋Š” ๊ฑธ ๋ชป ๋ณธ ๊ฒƒ ๊ฐ™๋‹ค.
    • ๋ฌธ์„œ๊ฐ€ ์•„๋‹ˆ๋ผ ์ œํ’ˆ์ฒ˜๋Ÿผ ์ƒ๊ฐํ•˜๊ณ  ๋งŒ๋“  ๊ฒƒ ๊ฐ™๋‹ค.
    • React์˜ ์ž…์ง€๋ฅผ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•œ ๋…ธ๋ ฅ์˜ ์ผํ™˜์ด ์•„๋‹๊นŒ?
  4. ์ฝ”๋“œ์—์„œ state ๋ณ€์ˆ˜๋ฅผ ํ•ด๋‹น ๊ฐ’์œผ๋กœ ๋Œ€์ž…ํ•˜์—ฌ ์ด๋ฅผ ์‹œ๊ฐํ™”ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

    <button
      onClick={() => {
        setNumber(0 + 1);
        setNumber(0 + 1);
        setNumber(0 + 1);
      }}
    >
      +3
    </button>
    • ๋ณ€์ˆ˜์— ๊ฐ’์„ ๋Œ€์ž…ํ•˜๋Š” ๊ฒƒ์ด ์ดํ•ดํ•˜๋Š” ๋ฐ ํฐ ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค. ์‹œ๊ฐํ™”์˜ ๊ฐ•๋ ฅํ•œ ํž˜์„ ๋А๊ผˆ์–ด์š”!
    • ์ €๋„ ์ด ๋ถ€๋ถ„ ๋ณด๋ฉด์„œ ์•„ ์ด๊ฑฐ๊ตฌ๋‚˜! ํ•˜๊ณ  ๊ฐํƒ„ํ–ˆ์–ด์š”.

Queueing a Series of State Updates

  1. React๋Š” state ์—…๋ฐ์ดํŠธ๋ฅผ ํ•˜๊ธฐ ์ „์— ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ์˜ ๋ชจ๋“  ์ฝ”๋“œ๊ฐ€ ์‹คํ–‰๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฝ๋‹ˆ๋‹ค.

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

    react batching
    • ๊น”๋”ํ•œ ๋น„์œ ๋ผ ์ดํ•ด๊ฐ€ ์ž˜ ๋˜๋„ค์š”.
    • ๊ธฐ์–ต์— ๋‚จ๊ฒจ๋‘๊ณ  ์‹ถ์€ ๋น„์œ ๋‹ค.
    • ๋งˆ์ง€๋ง‰์œผ๋กœ ๊ฐ€์ ธ๊ฐ€๋Š” ๊ฑด ์ฃผ๋ฌธ์ด ๋ชจ๋‘ ๋๋‚œ ๋’ค๋ผ๋Š” ๊ฑธ ํ•œ ์žฅ๋ฉด์œผ๋กœ ์ž˜ ์„ค๋ช…ํ–ˆ๋‹ค.
  3. ํ”ํ•œ ์‚ฌ๋ก€๋Š” ์•„๋‹ˆ์ง€๋งŒ, ๋‹ค์Œ ๋ Œ๋”๋ง ์ „์— ๋™์ผํ•œ state ๋ณ€์ˆ˜๋ฅผ ์—ฌ๋Ÿฌ ๋ฒˆ ์—…๋ฐ์ดํŠธ ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด setNumber(number + 1) ์™€ ๊ฐ™์€ ๋‹ค์Œ state ๊ฐ’์„ ์ „๋‹ฌํ•˜๋Š” ๋Œ€์‹ , setNumber(n => n + 1) ์™€ ๊ฐ™์ด ์ด์ „ ํ์˜ state๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๋‹ค์Œ state๋ฅผ ๊ณ„์‚ฐํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    • ๊ณต์‹ ๋ฌธ์„œ๋Š” ํ”ํ•œ ์‚ฌ๋ก€๊ฐ€ ์•„๋‹ˆ๋ผ๊ณ  ํ•˜์ง€๋งŒ, ์ €๋Š” ์ด๊ฑธ ์—„์ฒญ ์ƒ์Šต์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์–ด์„œ ๋ฐ˜์„ฑํ•˜๊ฒŒ ๋˜๋„ค์š”. ๋ณ€์ˆ˜ ๊ด€๋ฆฌ ์‹œ ๋ฐ˜๋“œ์‹œ state๋กœ ๊ด€๋ฆฌํ•ด์•ผํ•˜๋Š”์ง€, ์•„๋‹ˆ๋ฉด ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์ด ์žˆ๋Š”์ง€ ๊ณ ๋ฏผํ•ด๋ณด๋Š” ์Šต๊ด€์„ ๋“ค์—ฌ์•ผ๊ฒ ์Šต๋‹ˆ๋‹ค.
    • ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์ด ์ดˆ๊ธฐ ๊ธฐํš๊ณผ ๊ณ„์† ๋‹ฌ๋ผ์ง€๊ณ  ์„ธ๋ถ€ ์‚ฌํ•ญ์ด ๋ถ™์œผ๋ฉด์„œ ์ฒ˜์Œ ์„ค๊ณ„๋ณด๋‹ค ํฌ๊ณ  ๋ณต์žกํ•ด์ง€๋ฉด ๋ณ€์ˆ˜๋ฅผ ํ•˜๋‚˜ ํ•˜๋‚˜ ๊ณ ๋ คํ•˜๊ธฐ ์–ด๋ ค์›Œ ์ผ๋‹จ state์— ๋•Œ๋ ค๋ฐ•๊ธฐ๋„ ํ–ˆ๋‹ค.
  4. ์—ฌ๊ธฐ์„œ n => n + 1 ์€ ์—…๋ฐ์ดํ„ฐ ํ•จ์ˆ˜(updater function)๋ผ๊ณ  ๋ถ€๋ฆ…๋‹ˆ๋‹ค. ์ด๋ฅผ state ์„ค์ •์ž ํ•จ์ˆ˜์— ์ „๋‹ฌ ํ•  ๋•Œ,

    1. React๋Š” ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ์˜ ๋‹ค๋ฅธ ์ฝ”๋“œ๊ฐ€ ๋ชจ๋‘ ์‹คํ–‰๋œ ํ›„์— ์ด ํ•จ์ˆ˜๊ฐ€ ์ฒ˜๋ฆฌ๋˜๋„๋ก ํ์— ๋„ฃ์Šต๋‹ˆ๋‹ค.
    2. ๋‹ค์Œ ๋ Œ๋”๋ง ์ค‘์— React๋Š” ํ๋ฅผ ์ˆœํšŒํ•˜์—ฌ ์ตœ์ข… ์—…๋ฐ์ดํŠธ๋œ state๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
    • updater function๋Š” ๊ทธ๋ƒฅ ์ด์ „ ๊ฐ’์„ ๊ฐ€์ ธ์™€์„œ ๊ณ„์‚ฐํ•˜๋ ค๊ณ  ํ•  ๋•Œ๋งŒ ์‚ฌ์šฉํ–ˆ๋Š”๋ฐ ๋ Œ๋”๋ง๊ณผ ๊ด€๋ จ์ด ๊นŠ์—ˆ๋„ค์š”. ํ•จ์ˆ˜๊ฐ€ ๊ทธ๋ƒฅ ์‹คํ–‰๋œ๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ์ง€ ํ์— ๋„ฃ๋Š” ๋™์ž‘์ด ๋น„ํ•˜์ธ๋“œ์—์„œ ๋ฒŒ์–ด์ง€๊ณ  ์žˆ๋‹ค๋Š” ๊ฑธ ๋ชฐ๋ž๊ณ  ์œ„์˜ ์˜ˆ์ œ์ฒ˜๋Ÿผ ๊ฐ™์€ setState๋ฅผ ์—ฌ๋Ÿฌ ๋ฒˆ ํ˜ธ์ถœํ•ด๋ณธ ์ ์ด ์—†์–ด์„œ ์˜ˆ์ƒ ๋ฐ–์˜ ๊ฒฐ๊ณผ์— ๋‹นํ™ฉํ–ˆ์Šต๋‹ˆ๋‹ค.
    1. setNumber(number + 5): number ๋Š” 0 ์ด๋ฏ€๋กœ setNumber(0 + 5)์ž…๋‹ˆ๋‹ค. React๋Š” โ€5๋กœ ๋ฐ”๊พธ๊ธฐโ€ ๋ฅผ ํ์— ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.
    2. setNumber(n => n + 1): n => n + 1 ๋Š” ์—…๋ฐ์ดํ„ฐ ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค. React๋Š” ์ด ํ•จ์ˆ˜๋ฅผ ํ์— ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.
    3. setNumber(42): React๋Š” โ€42๋กœ ๋ฐ”๊พธ๊ธฐโ€ ๋ฅผ ํ์— ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.
    • ๋ฒ„๊ทธ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋Š”๋ฐ ์›์ธ๋ฅผ ํŒŒ์•…ํ•˜๊ธฐ ํž˜๋“ค ๋•Œ, ์ด๋Ÿฐ ์‹์œผ๋กœ ํ•ด๋‹น ์ฝ”๋“œ๊ฐ€ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ณผ์ •์„ ์ž์—ฐ์–ด๋กœ ๋ฐ”๊พธ์–ด ์ ์–ด๋ณด๋Š” ๊ฒƒ๋„ ์ข‹์€ ๋ฐฉ๋ฒ•์ธ ๊ฒƒ ๊ฐ™์•„์š”.
    • Rubber duck debugging์ด ๋– ์˜ฌ๋ž๋‹ค.
    • ์•Œ ์ˆ˜ ์—†๋Š” ์˜ค๋ฅ˜๋ฅผ ๋‹ค๋ฅธ ๊ฐœ๋ฐœ์ž ๋ถ„์—๊ฒŒ ์„ค๋ช…ํ•˜๋ ค๊ณ  ์ž‘์„ฑํ•˜๋‹ค๊ฐ€ ๊ฐ‘์ž๊ธฐ ๋ฒ„๊ทธ์˜ ์›์ธ์„ ๊นจ๋‹ซ๊ฒŒ ๋˜๋Š” ๊ฒฝ์šฐ๋„ ์žˆ๋‹ค.
  5. ์—…๋ฐ์ดํ„ฐ ํ•จ์ˆ˜๋Š” ์ˆœ์ˆ˜ํ•ด์•ผ ํ•˜๋ฉฐ ๊ฒฐ๊ณผ๋งŒ ๋ฐ˜ํ™˜ ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์—…๋ฐ์ดํ„ฐ ํ•จ์ˆ˜ ๋‚ด๋ถ€์—์„œ state๋ฅผ ๋ณ€๊ฒฝํ•˜๊ฑฐ๋‚˜ ๋‹ค๋ฅธ ์‚ฌ์ด๋“œ ์ดํŒฉํŠธ๋ฅผ ์‹คํ–‰ํ•˜๋ ค๊ณ  ํ•˜์ง€ ๋งˆ์„ธ์š”.

    • ์—…๋ฐ์ดํ„ฐ ํ•จ์ˆ˜ ๋‚ด์—์„œ ๋‹ค๋ฅธ๊ฑธ ํ•˜๋ ค๊ณ  ํ–ˆ๋˜ ์ œ ์ž์‹ ์„ ๋ฐ˜์„ฑํ•ฉ๋‹ˆ๋‹ค..
  6. ๋ช…๋ช… ๊ทœ์น™ ์—…๋ฐ์ดํ„ฐ ํ•จ์ˆ˜ ์ธ์ˆ˜์˜ ์ด๋ฆ„์€ ํ•ด๋‹น state ๋ณ€์ˆ˜์˜ ์ฒซ ๊ธ€์ž๋กœ ์ง€์ •ํ•˜๋Š” ๊ฒƒ์ด ์ผ๋ฐ˜์ ์ž…๋‹ˆ๋‹ค.

    setEnabled(e => !e);
    setLastName(ln => ln.reverse());
    setFriendCount(fc => fc * 2);
    

    ์ข€ ๋” ์ž์„ธํ•œ ์ฝ”๋“œ๋ฅผ ์„ ํ˜ธํ•˜๋Š” ๊ฒฝ์šฐ setEnabled(enabled => !enabled)์™€ ๊ฐ™์ด ์ „์ฒด state ๋ณ€์ˆ˜ ์ด๋ฆ„์„ ๋ฐ˜๋ณตํ•˜๊ฑฐ๋‚˜, setEnabled(prevEnabled => !prevEnabled)์™€ ๊ฐ™์€ ์ ‘๋‘์‚ฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๋„๋ฆฌ ์‚ฌ์šฉ๋˜๋Š” ๊ทœ์น™์ž…๋‹ˆ๋‹ค.

    • ์ด๋Ÿฐ ์ปจ๋ฒค์…˜์ด ์žˆ๋Š” ์ค„ ์ฒ˜์Œ ์•Œ์•˜๋„ค์š”.. ์ง€๊ธˆ๊นŒ์ง€ setData(prev => !prev) ๊ฐ™์€ ์‹์œผ๋กœ ๋งŽ์ด ์‚ฌ์šฉํ–ˆ๋Š”๋ฐ ์ข€ ๋” ์‹œ๋ฉ˜ํ‹ฑํ•˜๊ฒŒ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋„๋ก ๋…ธ๋ ฅํ•ด์•ผ๊ฒ ์Šต๋‹ˆ๋‹ค~
    • ์ฝ๊ธฐ ์ข‹์€ ์ฝ”๋“œ๋Š” ์ด๋Ÿฐ ๋””ํ…Œ์ผ์ด ๋ชจ์—ฌ์„œ ๊ฒฐ์ •๋œ๋‹ค.
    • prev์™€ ๊ฐ™์€ ํ‘œํ˜„์„ ์‚ฌ์šฉํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ๋ณด๊ณ  ๋ฐฐ์›Œ์„œ ๊ทธ๋ ‡๊ฒŒ ์จ์™”๋Š”๋ฐ ์ข‹์€ ์ปจ๋ฒค์…˜์„ ๋ฐฐ์›Œ๊ฐ‘๋‹ˆ๋‹ค! ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ์˜ ์ปจ๋ฒค์…˜์ผ ๊ฒƒ ๊ฐ™์•„์š”.
  7. Challenge 1 of 2: ์š”์ฒญ ์นด์šดํ„ฐ๋ฅผ ๊ณ ์ณ๋ณด์„ธ์š”.

    • ์ด ์ฑŒ๋ฆฐ์ง€ ์žฌ๋ฐŒ์–ด๋ณด์ด๋„ค์š”! ์Šคํ„ฐ๋”” ๋๋‚˜๊ณ  ํ˜ผ์ž ์‹œ๋„ํ•ด๋ด์•ผ๊ฒ ์Šต๋‹ˆ๋‹น

Updating Objects in State

  1. ํ•˜์ง€๋งŒ ๋ฆฌ์•กํŠธ state์˜ ๊ฐ์ฒด๋“ค์ด ๊ธฐ์ˆ ์ ์œผ๋กœ ๋ณ€๊ฒฝ ๊ฐ€๋Šฅํ• ์ง€๋ผ๋„, ์ˆซ์ž, ๋ถˆ๋ฆฌ์–ธ, ๋ฌธ์ž์—ด๊ณผ ๊ฐ™์ด ๋ถˆ๋ณ€์„ฑ์„ ๊ฐ€์ง„ ๊ฒƒ์ฒ˜๋Ÿผ ๋‹ค๋ฃจ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ฐ์ฒด๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ๋Œ€์‹  ๊ต์ฒดํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

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

    • ์ฝ๊ธฐ์ „์šฉ์ด๋ผ๊ณ  ํ•˜๋‹ˆ๊นŒ ์™€๋‹ฟ์•„์„œ ์ข‹์•„์š”.
  3. <div
      onPointerMove={(e) => {
        position.x = e.clientX;
        position.y = e.clientY;
      }}
    />
    • ์ด๋Ÿฐ ์ด๋ฒคํŠธ๊ฐ€ ์žˆ๊ตฐ์š”..! ์ง€๋‚œ ์‹œ๊ฐ„์— ํ–ˆ๋˜ ์ด์•ผ๊ธฐ์— ์ด์–ด, ์ด๋Ÿฐ html๊ธฐ๋ณธ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์žฌ๋ฐŒ๋Š” ๊ฑธ ๋งŽ์ด ๋งŒ๋“ค ์ˆ˜ ์žˆ์„ ๊ฒƒ ๊ฐ™์•„์š”
  4. ํ•˜์ง€๋งŒ ์ด ์ฝ”๋“œ๋Š” ๋ฐฉ๊ธˆ ์ƒ์„ฑํ•œ ์ƒˆ๋กœ์šด ๊ฐ์ฒด๋ฅผ ๋ณ€๊ฒฝํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ ์ ˆํ•ฉ๋‹ˆ๋‹ค.

    const nextPosition = {};
    nextPosition.x = e.clientX;
    nextPosition.y = e.clientY;
    setPosition(nextPosition);
    • setState ์•ˆ์— ๋“ค์–ด๊ฐˆ ๋กœ์ง์ด ์กฐ๊ธˆ ๋ณต์žกํ•˜๋ฉด ๊ฐ€๋…์„ฑ์„ ์œ„ํ•ด์„œ ์œ„๋กœ ๋บ๋‹ˆ๋‹ค. ๊ณต์‹ ๋ฌธ์„œ๊ฐ€ ๊ถŒ์žฅํ•˜๋Š” ๋ฐฉ์‹์ด๋ผ๋‹ˆ ์ข‹๋„ค์š”!
  5. ์ด๊ฒƒ์€ โ€œ์ง€์—ญ ๋ณ€๊ฒฝ local mutationโ€ ์ด๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ๋ Œ๋”๋งํ•˜๋Š” ๋™์•ˆ ์ง€์—ญ ๋ณ€๊ฒฝ์„ ํ•  ์ˆ˜๋„ ์žˆ์œผ๋ฉฐ, ์ด๋Š” ์•„์ฃผ ํŽธ๋ฆฌํ•ฉ๋‹ˆ๋‹ค!

    • ์ด๋ฏธ ์ด๋Ÿฐ ๋ฐฉ์‹์„ ๋งŽ์ด ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์—ˆ๋Š”๋ฐ ์ง€์—ญ ๋ณ€๊ฒฝ local mutation์ด๋ผ๋Š” ๋ช…์นญ์ด ์žˆ์—ˆ๋„ค์š”. ๊ณต์‹์ด ํ—ˆ๋ฝํ•œ ๋ฐฉ์‹์ด๋ผ๋Š” ์ƒ๊ฐ์— ๋งˆ์Œ์ด ํŽธํ•ด์กŒ์Šต๋‹ˆ๋‹ค
    • ์—๋””ํ„ฐ๋ฅผ ๋‹ค๋ฃฐ ๋•Œ ์˜ˆ์‹œ ์ฝ”๋“œ์™€ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ์ž‘์„ฑํ–ˆ๋‹ค. ๊ธฐ์กด ์ฝ”๋“œ์™€ ์ผ๊ด€์„ฑ์„ ๋งž์ถ”๊ธฐ ์œ„ํ•ด ๋”ฐ๋ผํ–ˆ๋Š”๋ฐ ์™œ ๋ฌธ์ œ๊ฐ€ ์—†๋Š”์ง€ ์ดํ•ดํ•˜๊ฒŒ ๋˜๋‹ˆ๊นŒ ๋ถˆ์•ˆ๊ฐ์ด ์‚ฌ๋ผ์กŒ๋‹ค.
  6. Using a single event handler for multiple fields

    ์•„๋ž˜์—๋Š” ์ด์ „ ์˜ˆ์ œ์™€ ๊ฐ™์ง€๋งŒ, ์„ธ ๊ฐœ์˜ ๋‹ค๋ฅธ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ๋Œ€์‹  ํ•˜๋‚˜์˜ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์˜ˆ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

    function handleChange(e) {
      setPerson({
        ...person,
        [e.target.name]: e.target.value,
      });
    }
    • react-hook-form์—์„œ name์„ ํ•ญ์ƒ ์ž‘์„ฑํ•˜๋„๋ก ํ•˜๋Š”๋ฐ ๊ทธ๊ฒŒ ํ•˜๋‚˜์˜ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋กœ ์ œ์–ดํ•˜๊ธฐ ์œ„ํ•ด์„œ์˜€๊ตฐ์š”.
  7. obj1 ๊ฐ์ฒด๋Š” obj2 โ€œ์•ˆโ€์— ์—†์Šต๋‹ˆ๋‹ค. obj3 ๋˜ํ•œ obj1์„ โ€œ๊ฐ€๋ฆฌํ‚ฌโ€ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

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

    • ์ค‘์ฒฉ๋œ๊ฒŒ ์•„๋‹ˆ๋ผ ์„œ๋กœ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ๊ฒƒ์ด๋‹ค ๋ผ๋Š” ์ƒˆ๋กœ์šด ๊ฐœ๋…์„ ์–ป์–ด๊ฐ€๋„ค์š”!
  9. Immer๋Š” ํŽธ๋ฆฌํ•˜๊ณ , ๋ณ€๊ฒฝ ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋ฉฐ ๋ณต์‚ฌ๋ณธ ์ƒ์„ฑ์„ ๋„์™€์ฃผ๋Š” ์ธ๊ธฐ ์žˆ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ž…๋‹ˆ๋‹ค. Immer๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ž‘์„ฑํ•œ ์ฝ”๋“œ๋Š” โ€œ๋ฒ•์น™์„ ๊นจ๊ณ โ€ ๊ฐ์ฒด๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    • ์ด๋ฒˆ์—๋„ immer์— ๋Œ€ํ•œ ์ด์•ผ๊ธฐ๊ฐ€ ๋‚˜์™”๋Š”๋ฐ, ์˜ˆ์‹œ ์ฝ”๋“œ์™€ ๊ฐ™์€ ์ƒํ™ฉ์—์„œ๋ผ๋ฉด ๊ฝค ์œ ์šฉํ•ด๋ณด์ด๋„ค์š”๐Ÿ˜ฒ ์ค‘์ฒฉ ๊ฐ์ฒด๋ฅผ ๋‹ค๋ฃจ๋Š” ์ฝ”๋“œ๋ฅผ useImmer๋ผ๋Š” ์ผ์ข…์˜ ์ถ”์ƒํ™”๋œ hook์„ ์ด์šฉํ•ด ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์–ด ์ฝ”๋“œ๊ฐ€ ๊น”๋”ํ•ด์ง€๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค
  10. Immer๊ฐ€ ์ œ๊ณตํ•˜๋Š” draft๋Š” Proxy๋ผ๊ณ  ํ•˜๋Š” ์•„์ฃผ ํŠน๋ณ„ํ•œ ๊ฐ์ฒด ํƒ€์ž…์œผ๋กœ, ๋‹น์‹ ์ด ํ•˜๋Š” ์ผ์„ โ€œ๊ธฐ๋กโ€ ํ•ฉ๋‹ˆ๋‹ค.

    • react-hook-form์—์„œ formState๋ผ๋Š” ๊ฐ์ฒด๋ฅผ ์ œ๊ณตํ•˜๋Š”๋ฐ ์ด๊ฒƒ๋„ Proxy๋ฅผ ์“ด๋‹ค๊ณ  ์•Œ๊ณ  ์žˆ์–ด์š”. design and philosophy ์ฐธ๊ณ 
    • ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋„ ๊ณต๋ถ€ํ• ๊ฒŒ ๋งŽ์Œ์„ ๊นจ๋‹ซ์Šต๋‹ˆ๋‹ค.
  11. Why is mutating state not recommended in React?

    • ๋”ฅ ๋‹ค์ด๋ธŒ ๋‚ด์šฉ์„ ํ†ตํ•ด ๋ฒ„๊ทธ ๋ฐฉ์ง€ ์™ธ์—๋„ ๋ถˆ๋ณ€์„ฑ์„ ๊ถŒ์žฅํ•˜๋Š” ์ด์œ ๋ฅผ ๋” ์•Œ๊ฒŒ ๋˜์–ด ์ข‹์•˜์Šต๋‹ˆ๋‹ค.
  12. ๋ณดํŽธ์ ์ธ ๋ฆฌ์•กํŠธ ์ตœ์ ํ™” ์ „๋žต

    • ์˜์–ด ๊ณต์‹ ๋ฌธ์„œ์—์„œ๋Š” memo ํŽ˜์ด์ง€๋กœ ๋งํฌ๋ฅผ ๊ฑธ์–ด๋’€๋˜๋ฐ ์—ฌ๊ธฐ์„œ๋Š” ์•„์ง ํŽ˜์ด์ง€๊ฐ€ ์—†๋‚˜๋ด์š”!
    • ๋งํฌ ๊นจ์ง„ ๊ฑฐ PR ์˜ฌ๋ ค๋ณด๋ฉด ์ข‹๊ฒ ๋„ค์š” ใ…Žใ…Ž
  13. Challenge 1 of 3: ์ž˜๋ชป๋œ state ์—…๋ฐ์ดํŠธ ๊ณ ์น˜๊ธฐ Challenge 2 of 3: ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ์ฐพ์•„ ๊ณ ์น˜์„ธ์š”

    • ์„ธ ๋ฒˆ์งธ ์ฑŒ๋ฆฐ์ง€๋Š” immer๋ฅผ ์‚ฌ์šฉํ•˜๋‹ค๋ณด๋‹ˆ ์ต์ˆ™ํ•˜์ง€ ๋ชปํ•ด์„œ ํ’€์ง€ ๋ชปํ–ˆ๋Š”๋ฐ ๋‚˜๋จธ์ง€ ์ฑŒ๋ฆฐ์ง€๋“ค ์žฌ๋ฏธ์žˆ์–ด์š”.

๐Ÿคทโ€โ™€๏ธ ์งˆ๋ฌธ

  • Q: ์˜คํ”ˆ ์†Œ์Šค ์ฝ”๋“œ๋ฅผ ๋œฏ์–ด ๋ณธ ์ ์ด ์žˆ๋Š”์ง€?
  • A: ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ ์ง€์›์„ ์•ˆ ํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋‚ด๋ถ€ ๋™์ž‘์„ ํ™•์ธํ•˜๊ณ  ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด๋ณธ ์ ์ด ์žˆ๋‹ค. ์ •๋ง ์ด๊ฑฐ ์—†์œผ๋ฉด ์ผ์ด ์•ˆ ๋œ๋‹ค ํ•˜๋Š” ๊ฒฝ์šฐ์— ๋œฏ์–ด ๋ณด๊ฒŒ ๋œ๋‹ค.
  • A: lodash์˜ debounce๋‚˜ throttle์„ ์‚ฌ์šฉํ•  ๋•Œ CTO๋‹˜์ด ์–ด๋–ป๊ฒŒ ๋งŒ๋“ค์—ˆ๋Š”์ง€ ์•Œ๊ณ  ์“ฐ๋Š” ๊ฒƒ์ด ์ข‹๋‹ค๊ณ  ํ•ด์„œ ์ฝ”๋“œ๋ฅผ ์ฐพ์•„ ๋ณธ ์ ์ด ์žˆ๋‹ค.
  • A: ํ† ์Šค์˜ slash๋Š” react์—์„œ ์“ธ ์ˆ˜ ์žˆ๋Š” ๋‹ค์–‘ํ•œ ์œ ํ‹ธ ์ปดํฌ๋„ŒํŠธ ๋ชจ์•„๋‘” ๋А๋‚Œ์ด๋ผ ํ•„์š”ํ•  ๋•Œ ์กฐ๊ธˆ์”ฉ ๊นŒ์„œ ๋ณธ๋‹ค. ๊ตญ๋‚ด์—์„œ๋„ ์ด๋ ‡๊ฒŒ ์˜คํ”ˆ์†Œ์Šค๋ฅผ ๊ณต๊ฐœํ•˜๊ณ  ๋ฉ”์ธํ…Œ์ด๋„ˆ๋กœ ์ฐธ์—ฌํ•˜๋Š” ์‚ฌ๋žŒ๋“ค์ด ์žˆ๋‹ค๋‹ˆ!

๐Ÿ’ก ์ •๋ณด

ko.javascript.info

  • React๋„ ์ถ”์ฒœํ•˜๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํ•™์Šต ์ž๋ฃŒ
  • ๋ฒˆ์—ญ ํ”„๋กœ์ ํŠธ๋ฅผ ์ถ”์ง„ํ•œ ์ด๋ณด๋ผ๋‹˜์˜ ์†Œ๊ฐœ ๊ธ€

Updating Arrays in State

  1. ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๊ณ  ๋ฐฐ์—ด ์—…๋ฐ์ดํŠธํ•˜๊ธฐ

    • ๋ฐฐ์—ด์„ state๋กœ ๊ฐ€์งˆ ๋•Œ ์ผ์–ด๋‚ ๋งŒํ•œ ์ƒํ™ฉ์— ๋Œ€ํ•œ ์˜ˆ์ œ๋“ค์ด ์•„๋ž˜์— ์ž˜ ๋‚˜์™€์žˆ์–ด์„œ ๋งŽ์ด ์ฐธ๊ณ ํ•˜๊ฒŒ ๋  ๊ฒƒ ๊ฐ™์•„์š”!
    • ์ฒ˜์Œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ๋ฐฐ์šธ ๋•Œ ์ด๋Ÿฐ ์ผ€์ด์Šค๋ฅผ ํ•˜๋‚˜์”ฉ ๋งž๋‹ฅ๋œจ๋ฆด ๋•Œ๋งˆ๋‹ค ๊ตฌ๊ธ€๋งํ•˜๋ฉฐ ํ’€์—ˆ๋˜ ๊ธฐ์–ต์ด ๋‚˜๋„ค์š”.
  2. ๋‹ค์Œ์€ ์ผ๋ฐ˜์ ์ธ ๋ฐฐ์—ด ์—ฐ์‚ฐ์— ๋Œ€ํ•œ ์ฐธ์กฐ ํ‘œ์ž…๋‹ˆ๋‹ค. React state ๋‚ด์—์„œ ๋ฐฐ์—ด์„ ๋‹ค๋ฃฐ ๋•, ์™ผ์ชฝ ์—ด์— ์žˆ๋Š” ํ•จ์ˆ˜๋“ค์˜ ์‚ฌ์šฉ์„ ํ”ผํ•˜๋Š” ๋Œ€์‹ , ์˜ค๋ฅธ์ชฝ ์—ด์— ์žˆ๋Š” ํ•จ์ˆ˜๋“ค์„ ์„ ํ˜ธํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

    ๋น„์„ ํ˜ธ (๋ฐฐ์—ด์„ ๋ณ€๊ฒฝ) ์„ ํ˜ธ (์ƒˆ ๋ฐฐ์—ด์„ ๋ฐ˜ํ™˜)
    ์ถ”๊ฐ€ push, unshift concat, [...arr] ์ „๊ฐœ ์—ฐ์‚ฐ์ž (์˜ˆ์‹œ)
    ์ œ๊ฑฐ pop, shift, splice filter, slice (์˜ˆ์‹œ)
    ๊ต์ฒด splice, arr[i] = ... ํ• ๋‹น map (์˜ˆ์‹œ)
    ์ •๋ ฌ reverse, sort ๋ฐฐ์—ด์„ ๋ณต์‚ฌํ•œ ์ดํ›„ ์ฒ˜๋ฆฌ (์˜ˆ์‹œ)
    • ํ•œ๋ˆˆ์— ๋ณผ ์ˆ˜ ์žˆ๊ฒŒ ํ‘œ๋กœ ์ •๋ฆฌ๋˜์–ด ์žˆ์–ด์„œ ์ข‹์•„์š”! ๊ทธ๋Ÿฌ๊ณ ๋ณด๋‹ˆ UI ์ž‘์—…ํ•  ๋•Œ๋Š” ์˜ค๋ฅธ์ชฝ๋งŒ ๊ฑฐ์˜ ์‚ฌ์šฉํ–ˆ๋„ค์š”.
  3. ๋˜๋Š” ๋‘ ์—ด์˜ ํ•จ์ˆ˜๋ฅผ ๋ชจ๋‘ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” Immer๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    • ๊ณต์‹ ๋ฌธ์„œ๊ฐ€ ์—„์ฒญ ์ ๊ทน์ ์œผ๋กœ Immer๋ฅผ ์˜์—…ํ•˜๋Š”๊ตฐ์š”.. Immer ๋ฉ”์ธํ…Œ์ด๋„ˆ๊ฐ€ ๊ถ๊ธˆํ•ด์ ธ์„œ ์ฐพ์•„๋ดค๋Š”๋ฐ ๋ฉ”ํƒ€ ๊ทผ๋ฌดํ•˜๋Š” ๊ฐœ๋ฐœ์ž์‹œ๋„ค์š” Github ๋งํฌ
    • ๋‹ค ์ด์œ ๊ฐ€ ์žˆ์—ˆ๊ตฐ์š”. ๐Ÿ˜ ์ƒํƒœ์— ๋ณต์žกํ•œ ๊ฐ์ฒด๋ฅผ ๋„ฃ์œผ๋ฉด ์œ ์šฉํ•  ๊ฒƒ ๊ฐ™์€๋ฐ ๋˜ ๊ฐ์ฒด๊ฐ€ ๋„ˆ๋ฌด ๋ณต์žกํ•ด์ง€๋ฉด ์•ˆ ๋˜๋Š” ๊ฑฐ ์•„๋‹Œ๊ฐ€ ํ•˜๋Š” ์ƒ๊ฐ์ด ๋“ค์–ด์š”.
  4. ์•ˆํƒ€๊น์ง€๋งŒ, slice์™€ splice ํ•จ์ˆ˜๋Š” ์ด๋ฆ„์ด ๋น„์Šทํ•˜์ง€๋งŒ ๋ชน์‹œ ๋‹ค๋ฆ…๋‹ˆ๋‹ค.

    • slice๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฐฐ์—ด ๋˜๋Š” ๊ทธ ์ผ๋ถ€๋ฅผ ๋ณต์‚ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    • splice๋Š” ๋ฐฐ์—ด์„ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค. (ํ•ญ๋ชฉ์„ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค.)

    React์—์„œ๋Š”, state์˜ ๊ฐ์ฒด๋‚˜ ๋ฐฐ์—ด์„ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๋Š” ๊ฒŒ ์ข‹๊ธฐ ๋•Œ๋ฌธ์— slice (p๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค!)๋ฅผ ํ›จ์”ฌ ๋” ์ž์ฃผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

    • ์ด ๋‘๊ฐœ๋ฅผ ์ €๋„ ์ข…์ข… ํ—ท๊ฐˆ๋ ค์„œ ๋ฆฌ๋งˆ์ธ๋“œ๋ฅผ ์œ„ํ•œ ๊ธฐ๋ก์ฐจ ์–ด๋…ธํ…Œ์ด์…˜ ๋‹ฌ์•„๋‘ก๋‹ˆ๋‹ค
  5. ์ค‘์ฒฉ๋œ state๋ฅผ ์—…๋ฐ์ดํŠธํ•  ๋•Œ, ์—…๋ฐ์ดํŠธํ•˜๋ ค๋Š” ์ง€์ ๋ถ€ํ„ฐ ์ตœ์ƒ์œ„ ๋ ˆ๋ฒจ๊นŒ์ง€์˜ ๋ณต์‚ฌ๋ณธ์„ ๋งŒ๋“ค์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

    • ์˜ˆ์ „์—๋Š” ์ด ์ž‘์—…์„ ๊ฐ„๋‹จํ•˜๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด lodash์˜ deepClone๊ฐ™์€ ๋ฉ”์†Œ๋“œ๋ฅผ ์‚ฌ์šฉํ–ˆ๋Š”๋ฐ, ์š”์ฆ˜์—๋Š” ๊ฑฐ์˜ ์ง€๋‚œ ์‹œ๊ฐ„์— ์†Œ๊ฐœ๋“œ๋ฆฐ structuredClone ๋ฉ”์†Œ๋“œ๋กœ ๋Œ€์ฒดํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค~
  6. map์„ ์‚ฌ์šฉํ•˜๋ฉด ์ด์ „ ํ•ญ๋ชฉ์˜ ๋ณ€๊ฒฝ ์—†์ด ์—…๋ฐ์ดํŠธ๋œ ๋ฒ„์ „์œผ๋กœ ๋Œ€์ฒดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    • ๊ตณ์ด ๊นŠ์€ ๋ณต์‚ฌ๊นŒ์ง€ ๊ณ ๋ คํ•˜์ง€ ์•Š์•„๋„ ์†์‰ฝ๊ฒŒ+์•ˆ์ „ํ•˜๊ฒŒ ๊ฐ์ฒด์˜ ๋ถˆ๋ณ€์…ฉ์„ ์œ ์ง€ํ•˜๋ฉฐ state๋ฅผ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ด๊ตฐ์š”! ๊ด€์Šต์ ์œผ๋กœ ์ด๋ ‡๊ฒŒ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๊ธฐ๋Š” ํ–ˆ๋Š”๋ฐ, ์ •ํ™•ํ•œ ์ด์œ ๋ฅผ ์•Œ๊ฒŒ๋˜์–ด ์ข‹์Šต๋‹ˆ๋‹น