React study: ๋ฆฌ์•กํŠธ์˜ ๊ธฐ๋ณธ ์›๋ฆฌ

@choi2021 ยท January 23, 2023 ยท 17 min read

๐Ÿ˜‹ ๋ฆฌ์•กํŠธ์˜ ๊ธฐ๋ณธ ์›๋ฆฌ

๋ฉด์ ‘์„ ํ†ตํ•ด ๋ฆฌ์•กํŠธ์˜ ๊ธฐ๋ณธ๋˜๋Š” ์งˆ๋ฌธ๋“ค์„ ๋ฐ›์•˜์„ ๋•Œ ์•ˆ๋‹ค๋ผ๊ณ  ์ž์‹ ํ–ˆ์—ˆ์ง€๋งŒ, ์ œ๋Œ€๋กœ ๋‹ต๋ณ€์„ ํ•˜์ง€ ๋ชปํ•˜๋Š” ๊ฒฝ์šฐ๋„ ๋งŽ์•˜๋‹ค. ๋ฉด์ ‘์„ ๊ธฐํšŒ๋กœ ๋ฆฌ์•กํŠธ๋ฅผ ๋” ๊นŠ์ด ์žˆ๊ฒŒ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ธฐ๋ณธ๋ถ€ํ„ฐ ๋‹ค์‹œ ์ •๋ฆฌํ•ด๋ณด๋ ค ํ•œ๋‹ค.

๐ŸŽ† ๋ฆฌ์•กํŠธ๋ž€

๋ฆฌ์•กํŠธ๋ž€ UI๋ฅผ ์œ„ํ•œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ผ๊ณ  ์ •์˜ํ•  ์ˆ˜ ์žˆ๋‹ค. ๋˜ ๋‹ค๋ฅด๊ฒŒ ์„ค๋ช…ํ•˜์ž๋ฉด ์ปดํฌ๋„ŒํŠธ๋“ค์˜ ์ง‘ํ•ฉ์œผ๋กœ๋„ ๋งํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ์ปดํฌ๋„ŒํŠธ์˜ ๋ฐ์ดํ„ฐ์ธ Props์™€ state์— ๋Œ€ํ•œ ์งˆ๋ฌธ๊ณผ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์–ด๋–ป๊ฒŒ ์„ค๊ณ„ํ•˜๋Š” ์ง€์— ๋Œ€ํ•ด ์งˆ๋ฌธ์„ ๋ฐ›์•˜์—ˆ๋‹ค.

โ™Ÿ ์ปดํฌ๋„ŒํŠธ์˜ ๋ฐ์ดํ„ฐ: Props์™€ State

์ปดํฌ๋„ŒํŠธ๋Š” ๋ถ€๋ชจ๋กœ ๋ถ€ํ„ฐ ์ „๋‹ฌ๋ฐ›์•„ ์ˆ˜์ •ํ•  ์ˆ˜ ์—†๋Š” ๋ฐ์ดํ„ฐ์ธ Props์™€ ์ž์ฒด์ ์œผ๋กœ ๊ฐ€์ง€๋ฉฐ ์—…๋ฐ์ดํŠธ ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐ์ดํ„ฐ์ธ State๊ฐ€ ์žˆ๋‹ค. ๋‘ ๊ฐ€์ง€ ๋ฐ์ดํ„ฐ์˜ ๋ณ€ํ™”๋Š” ๋ฆฌ๋žœ๋”๋ง์˜ Trigger๊ฐ€ ๋˜์–ด ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ฆฌ๋ Œ๋”๋งํ•˜๊ฒŒ ๋œ๋‹ค. ์ด๋•Œ ์ค‘์š”ํ•œ ๊ฒƒ์ด ๋‘ ๋ฐ์ดํ„ฐ์˜ ๋ณ€ํ™”๋ฅผ ์•Œ๋ ค์ฃผ๊ธฐ ์œ„ํ•ด ๋ถˆ๋ณ€์„ฑ์„ ์ง€์ผœ์•ผ ํ•œ๋‹ค๋Š” ์ ์ด๋‹ค.

react flow
react flow

์›์‹œํ˜• ํƒ€์ž…์˜ ๊ฒฝ์šฐ ๊ฐ’์ด ๋ณ€ํ•˜๋ฉด ์ƒˆ๋กœ์šด ๋ฉ”๋ชจ๋ฆฌ ์ฃผ์†Œ์— ๊ฐ’์„ ํ• ๋‹นํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ’์˜ ๋ณ€ํ™” = ๋ฉ”๋ชจ๋ฆฌ ์ฃผ์†Œ์˜ ๋ณ€ํ™”๋กœ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ํ•˜์ง€๋งŒ ๊ฐ์ฒด ํƒ€์ž…์ธ ๊ฐ์ฒด, ๋ฐฐ์—ด, ํ•จ์ˆ˜ ๋“ฑ์€ ์‹ค์ œ ๊ฐ’์ด ์•„๋‹Œ ๊ฐ์ฒด๋ฅผ ์ €์žฅํ•˜๊ณ  ์žˆ๋Š” ๋ฉ”๋ชจ๋ฆฌ ํž™์˜ ์ฐธ์กฐ๊ฐ’์„ ๊ฐ’์— ํ• ๋‹นํ•˜๊ณ , ์†์„ฑ ๊ฐ’์ด ๋ณ€ํ™”ํ•œ๋‹ค๊ณ  ํ•ด์„œ ์ƒˆ๋กœ์šด ์ฃผ์†Œ๋กœ ํ• ๋‹นํ•˜์ง€ ์•Š๋Š”๋‹ค. ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ์ฒด ํƒ€์ž…์—์„œ ๊ฐ’์˜ ๋ณ€ํ™” != ๋ฉ”๋ชจ๋ฆฌ ์ฃผ์†Œ์˜ ๋ณ€ํ™”๊ฐ€ ๋œ๋‹ค.

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

๊ฐ์ฒด์˜ ์†์„ฑ์ด ๋ฐ”๋€Œ๋ฉด ๊ฐ์ฒด ์ž์ฒด์˜ ์ฐธ์กฐ ๊ฐ’์„ ๋ฐ”๊ฟ”์ฃผ๊ธฐ ์œ„ํ•ด์„œ spread operator, map, filter์™€ ๊ฐ™์ด ์›๋ณธ ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์ •ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์ƒˆ๋กœ์šด ๊ฐ์ฒด๋ฅผ ๋งŒ๋“œ๋Š” ๋ฐฉ์‹์œผ๋กœ ์ƒํƒœ๋ฅผ ๋ณ€ํ™”์‹œ์ผœ, ๋ฆฌ์•กํŠธ์˜ ํšจ์œจ์ ์ธ ์ƒํƒœ ์—…๋ฐ์ดํŠธ๊ฐ€ ๊ฐ€๋Šฅํ•˜๊ฒŒ ๋œ๋‹ค.

๐Ÿ˜€ ์ œ์–ด ์ปดํฌ๋„ŒํŠธ์™€ ๋น„์ œ์–ด ์ปดํฌ๋„ŒํŠธ

์ œ์–ด ์ปดํฌ๋„ŒํŠธ์™€ ๋น„์ œ์–ด ์ปดํฌ๋„ŒํŠธ๋Š” ๋ฉด์ ‘์—์„œ ์ฒ˜์Œ๋“ค์€ ๋‹จ์–ด์˜€๋‹ค. ๊ฐ๊ฐ์— ๋Œ€ํ•ด ์„ค๋ช…ํ•ด ๋ณด๋ผ๋Š” ์งˆ๋ฌธ์— ๋ฐ”๋กœ ์ž˜ ๋ชจ๋ฅด๊ฒ ๋‹ค ํ–ˆ์ง€๋งŒ input๊ณผ form์„ ์ƒ๊ฐํ•˜๋ฉด ๋‹ตํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ ๊ฐ™๋‹ค๊ณ  ํžŒํŠธ๋ฅผ ์ฃผ์…”์„œ ์ œ์–ด ์ปดํฌ๋„ŒํŠธ์— ๋Œ€ํ•ด์„œ ๋งŒ ์„ค๋ช…ํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.

์ œ์–ด ์ปดํฌ๋„ŒํŠธ

์ œ์–ด ์ปดํฌ๋„ŒํŠธ๋Š” model์— ํ•ด๋‹นํ•˜๋Š” data, ์ฆ‰ ์ƒํƒœ์™€ ๋ฐ”์ธ๋”ฉ๋˜์–ด ์ƒํƒœ์— ๋”ฐ๋ผ ๊ฐ’์ด ๋ฐ”๋€Œ๋Š” ์ปดํฌ๋„ŒํŠธ๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ๋‹ค. ์˜ˆ๋กœ input์˜ ๊ฒฝ์šฐ ์‚ฌ์šฉ์ž์˜ ์ž…๋ ฅ์„ ํ†ตํ•ด ์ƒํƒœ๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๊ณ  ์—…๋ฐ์ดํŠธํ•œ ์ƒํƒœ๋ฅผ value์†์„ฑ์œผ๋กœ ์ „๋‹ฌํ•ด์ค˜ ์ƒํƒœ์™€ ํ•ญ์ƒ ๋™๊ธฐํ™”๋  ์ˆ˜ ์žˆ๊ฒŒ ํ•œ๋‹ค.

import { useState } from "react"

const App = () => {
  const [value, setValue] = useState("")
  const handleChange = e => {
    setName(e.target.value)
  }

  return (
    <form onSubmit={handleSubmit}>
      <input
        type="text"
        placeholder="Enter Name"
        value={value}
        onChange={handleChange}
      />
      <button>Add</button>
    </form>
  )
}

export default App

์ต์ˆ™ํ•œ ์œ„ ์ฝ”๋“œ ๋ชจ์Šต์—์„œ ๊ณผ์ •์„ ์ •๋ฆฌํ•ด๋ณด๋ฉด 1) ์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅํ•œ๋‹ค. 2) ์ž…๋ ฅ๋œ ๊ฐ’์„ onChangeํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ•œ๋‹ค. 3) ์ƒํƒœ๋ฅผ value๋กœ ๋ฐ˜์˜ํ•œ๋‹ค ๋กœ ์„ธ๊ฐ€์ง€ step์œผ๋กœ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

๋น„์ œ์–ด ์ปดํฌ๋„ŒํŠธ

๋น„์ œ์–ด ์ปดํฌ๋„ŒํŠธ๋Š” ์ œ์–ด ์ปดํฌ๋„ŒํŠธ์™€ ๋‹ฌ๋ฆฌ ์ž…๋ ฅ์— ๋”ฐ๋ผ ์ƒํƒœ๋ฅผ ์—…๋ฐ์ดํŠธ ์‹œํ‚ค๊ณ  ์ƒํƒœ์™€ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ฐ”์ธ๋”ฉํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ, DOM์š”์†Œ์— ์ ‘๊ทผํ•ด ์ž…๋ ฅ๋œ ๊ฐ’์„ ๋ฐ›์•„์˜ค๋Š” ๋ฐฉ์‹์ด๋‹ค.

import { useRef } from "react"

const App = () => {
  const inputRef = useRef()

  const handleSubmit = event => {
    event.preventDefault()
    const name = inputRef.current.value
    console.log("Input value - ", this.inputRef.current.value)
  }

  return (
    <form onSubmit={handleSubmit}>
      <div>
        <label>Uncontrolled input </label>
        <input type="date" name="data" id="date-input" ref={this.inputRef} />
      </div>

      <button type="submit">Submit</button>
    </form>
  )
}

export default App

์œ„ ์ฝ”๋“œ์—์„œ ๊ณผ์ •์„ ์ •๋ฆฌํ•ด๋ณด๋ฉด 1) ์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅํ•œ๋‹ค 2) ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅธ๋‹ค 3) submit์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๊ณ  DOM์š”์†Œ์— ์ ‘๊ทผํ•ด ๊ฐ’์„ ์ฝ˜์†”๋กœ ํ˜ธ์ถœํ•œ๋‹ค๋กœ ์ •๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

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

๐Ÿงจ ๋ฆฌ์•กํŠธ์˜ re-rendering ์กฐ๊ฑด๊ณผ ๋ถˆํ•„์š”ํ•œ re-rendering ๋ง‰๊ธฐ

Re-rendering์˜ ์กฐ๊ฑด์€ ํฌ๊ฒŒ 2๊ฐ€์ง€๋กœ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

  • Props์™€ State์˜ ๋ณ€ํ™”
  • ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ์˜ re-rendering

์•ž์„œ ์„ค๋ช…ํ•œ Props๋Š” ๋ถ€๋ชจ๋กœ ๋ถ€ํ„ฐ ์ „๋‹ฌ๋ฐ›์€ ๋ฐ์ดํ„ฐ์ด๊ธฐ ๋•Œ๋ฌธ์— ์ „๋‹ฌํ•˜๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ๊ฐ์ฒดํƒ€์ž…์ผ ๊ฒฝ์šฐ์— ๋ถ€๋ชจ๊ฐ€ re-rendering๋˜์—ˆ์„ ๋•Œ ํ•ญ์ƒ ์ƒˆ๋กญ๊ฒŒ ๋ฐ์ดํ„ฐ๊ฐ€ ๋งŒ๋“ค์–ด์ ธ ์ „๋‹ฌ๋œ๋‹ค. ์™œ๋ƒํ•˜๋ฉด {}!=={}๋กœ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ ๊ฐ์ฒด๋Š” ํ•ญ์ƒ ์ƒˆ๋กœ์šด ๊ฐ’์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ์ƒˆ๋กœ์šด ๊ฐ’์ด props๋กœ ์ „๋‹ฌ๋˜๋ฏ€๋กœ ์ž์‹ ์ปดํฌ๋„ŒํŠธ์˜ re-rendering์œผ๋กœ ์ด์–ด์ง„๋‹ค.

๋ฆฌ์•กํŠธ๊ฐ€ ์„ฑ๋Šฅ ๋ณด์žฅํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์ •๋ฆฌํ•œ ์ด์ „ ๊ธ€์ฒ˜๋Ÿผ ๋ถˆํ•„์š”ํ•œ ์ž์‹์˜ re-rendering์„ ๋ง‰๊ธฐ ์œ„ํ•ด์„œ๋Š” props๋กœ ์ „๋‹ฌํ•˜๋Š” ๋ณ€์ˆ˜,ํ•จ์ˆ˜๊ฐ€ ํ•ญ์ƒ ์ƒˆ๋กญ๊ฒŒ ๋งŒ๋“ค์–ด์ง€์ง€ ์•Š์•„๋„ ๋œ๋‹ค๋ฉด useMemo์™€ useCallback์„ ํ†ตํ•ด ๋ฉ”๋ชจ์ด์ œ์ด์…˜์„ ํ•˜๊ณ  dependency๊ฐ€ ๋ฐ”๋€” ๋•Œ๋งŒ ์ƒˆ๋กญ๊ฒŒ ์ „๋‹ฌํ•˜๋Š” ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ๋˜ํ•œ Memo๋ฅผ ์ด์šฉํ•ด ์ปดํฌ๋„ŒํŠธ๋กœ ์ „๋‹ฌ๋˜๋Š” Props์˜ ๋ณ€ํ™”๊ฐ€ ์—†๋‹ค๋ฉด re-rendering์„ ํ•˜์ง€ ์•Š๊ฒŒ ์„ฑ๋Šฅ์„ ๊ฐœ์„ ํ•  ์ˆ˜ ์žˆ๋‹ค.

๐Ÿ•ถ ๋ฆฌ์•กํŠธ์˜ ๋ฐ์ดํ„ฐ ๋ฐ”์ธ๋”ฉ๊ณผ Flux ํŒจํ„ด

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

๋ฐ์ดํ„ฐ ๋ฐ”์ธ๋”ฉ์ด๋ž€ ํŽ˜์ด์ง€์— ๋ณด์—ฌ์งˆ View์™€ ๋ฐ์ดํ„ฐ๋ฅผ ์—ฐ๊ฒฐํ•˜๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค. ๋ฐ์ดํ„ฐ ๋ฐ”์ธ๋”ฉ์€ ๋‹จ๋ฐฉํ–ฅ๊ณผ ์–‘๋ฐฉํ–ฅ์œผ๋กœ ๋‚˜๋‰  ์ˆ˜ ์žˆ๋Š”๋ฐ ๋‹จ๋ฐฉํ–ฅ์˜ ๊ฒฝ์šฐ ๋ฐ์ดํ„ฐ๊ฐ€ ๋ณ€๊ฒฝ๋˜๋ฉด ํ…œํ”Œ๋ฆฟ๊ณผ ํ•จ๊ป˜ ๊ฒฐํ•ฉํ•ด ๋ทฐ๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•˜๊ณ , ์–‘๋ฐฉํ–ฅ์˜ ๊ฒฝ์šฐ ๋‹จ๋ฑกํ–ฅ๊ณผ ๊ฐ™์ด ๋ฐ์ดํ„ฐ์˜ ๋ณ€๊ฒฝ์„ ํ…œํ”Œ๋ฆฟ๊ณผ ํ•จ์ณ view๋กœ ๋ฐ˜์˜ํ•˜๋Š” ๊ฒƒ๊ณผ ํ•จ๊ป˜ View ๋ณ€ํ™”๋ฅผ ๋ฐ์ดํ„ฐ์— ๋ฐ˜์˜ํ•˜๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค.

flux
flux

๋ฆฌ์•กํŠธ๋Š” ๋‹จ๋ฐฉํ–ฅ ๋ฐ์ดํ„ฐ ๋ฐ”์ธ๋”ฉ์„ ์ด์šฉํ•œ๋‹ค. ์ปดํฌ๋„ŒํŠธ ๋‚ด๋ถ€์˜ ๋‹จ๋ฐฉํ–ฅ ๋ฐ์ดํ„ฐ ๋ฐ”์ธ๋”ฉ์€ useState๋ฅผ ํ†ตํ•ด ์ƒํƒœ๋ฅผ ๋งŒ๋“ค๊ณ , ๋งŒ๋“  ์ƒํƒœ๋ฅผ JSX๋ฅผ ํ†ตํ•ด HTML(View)๋กœ ๋ฐ˜์˜ํ•œ๋‹ค. UI๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐฑ์‹ ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์ด๋ฒคํŠธ๋ฅผ ์ด์šฉํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ์—…๋ฐ์ดํŠธ ํ•  ์ˆ˜ ์žˆ๋‹ค.

์ปดํฌ๋„ŒํŠธ ๊ฐ„์˜ ๋‹จ๋ฐฉํ–ฅ ๋ฐ์ดํ„ฐ ๋ฐ”์ธ๋”ฉ์€ ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ์—์„œ ์ž์‹ ์ปดํฌ๋„ŒํŠธ๋กœ ๋ฐ์ดํ„ฐ๊ฐ€ props๋ฅผ ํ†ตํ•ด ์ „๋‹ฌ๋˜๋Š” ๊ตฌ์กฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค. ์ด๋•Œ ๋ถ€๋ชจ์˜ ์ƒํƒœ๋ฅผ ์ž์‹ ์ปดํฌ๋„ŒํŠธ์—์„œ ๋ณ€ํ™”์‹œํ‚ค๊ธฐ ์œ„ํ•ด์„œ๋Š” props๋กœ ๋ถ€๋ชจ ์ƒํƒœ๋ฅผ ์—…๋ฐ์ดํŠธํ•  ์ˆ˜ ์žˆ๋Š” setState๋ฅผ props๋กœ ์ „๋‹ฌํ•ด ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค.

์ด๋Ÿฌํ•œ ๊ตฌ์กฐ๋ฅผ ํ†ตํ•ด ๊ฐ€์ง€๋Š” ์žฅ์ ์€ ํ•˜๋‚˜์˜ ๋ฐฉํ–ฅ์œผ๋กœ ๋ฐ์ดํ„ฐ๊ฐ€ ์ง„ํ–‰๋˜๊ธฐ ๋•Œ๋ฌธ์— ์ฝ”๋“œ ์ดํ•ด๊ฐ€ ์‰ฝ๊ณ  ๋””๋ฒ„๊น…์ด ์‰ฌ์šด ์žฅ์ ์„ ๊ฐ€์ง„๋‹ค. ๋‹จ์ ์€ ๋ณ€ํ™”๋ฅผ ๊ฐ์ง€ํ•˜๊ณ  ์—…๋ฐ์ดํŠธํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ํ•ญ์ƒ ์ž‘์„ฑํ•ด์•ผํ•˜๋Š” ๊ฒƒ์œผ๋กœ <input value={name}/>์—์„œ onChange ์ด๋ฒคํŠธ ํ•จ์ˆ˜๋ฅผ ํ•ญ์ƒ ์ „๋‹ฌํ•ด์ค˜์•ผํ•˜๋Š” ์ด์œ ๋ฅผ ์•Œ ์ˆ˜ ์žˆ์—ˆ๋‹ค.

๋‹จ๋ฐฉํ–ฅ ๋ฐ์ดํ„ฐ ๋ฐ”์ธ๋”ฉ์œผ๋กœ ๋ฆฌ์•กํŠธ๊ฐ€ ์ด๋ฃจ์–ด์ ธ์žˆ๋Š” ๊ฒƒ์„ ์ดํ•ดํ•˜๋ฉด์„œ ์ด๋Ÿฌํ•œ ๋ฐ์ดํ„ฐ์™€ View๋ฅผ ์–ด๋–ป๊ฒŒ ๊ด€๋ฆฌํ•  ๊ฑด์ง€์— ๋Œ€ํ•ด ์ •๋ฆฌํ•œ ๊ฒƒ์ด ๋ฐ”๋กœ ๋””์ž์ธ ํŒจํ„ด์ด๋ผ๋Š” ๊ฒƒ์„ ๊นจ๋‹ซ๊ฒŒ ๋˜์—ˆ๋‹ค. ์ตœ๊ทผ ๋ฉด์ ‘์—์„œ๋„ ๋””์ž์ธํŒจํ„ด์— ๋Œ€ํ•ด ๋ฌผ์–ด๋ณด์•˜์ง€๋งŒ ์•„๋Š”๊ฒŒ MVC๋ฐ–์— ์—†์–ด... ๊ทธ๊ฒƒ๋ฐ–์— ์„ค๋ช…ํ•  ์ˆ˜ ์—†์—ˆ๋‹ค.

mvc
mvc

์–‘๋ฐฉํ–ฅ ๋ฐ์ดํ„ฐ๋ฐ”์ธ๋”ฉ์œผ๋กœ MVCํŒจํ„ด์„ ์‚ฌ์šฉํ•˜๋˜ Facebook์€ ์ ์  ๋ณต์žกํ•ด์ง€๊ณ  ์˜ˆ์ธกํ•˜์ง€ ๋ชปํ•˜๋Š” ๋‹จ์ ์„ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ๋‹จ๋ฐฉํ–ฅ ์•„ํ‚คํƒ์ฒ˜์ธ Flux ํŒจํ„ด์„ ๋„์ž…ํ•œ๋‹ค.

mvc-2
mvc-2

Flux ํŒจํ„ด

Flux ํŒจํ„ด์€ ์‚ฌ์šฉ์ž๊ฐ€ View์—์„œ Action์„ ๋ฐœ์ƒ์‹œํ‚ค๋ฉด Dispatcher๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๊ฐ€ ์ €์žฅ๋˜์–ด์žˆ๋Š” Store๋กœ ์ „๋‹ฌ๋˜์–ด ๋ฐ์ดํ„ฐ๊ฐ€ ๋ณ€๊ฒฝ๋˜๊ณ , View๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๊ฒŒ ๋œ๋‹ค. ์ด๋Ÿฌํ•œ Flux ํŒจํ„ด์€ ๋‹น์‹œ์—๋Š” ๊ฐœ๋…์ ์ธ ์•„ํ‚คํ…์ฒ˜์˜€์ง€๋งŒ ๊ณง์ด์–ด ์ด๊ฒƒ์„ ๊ตฌํ˜„ํ•œ Redux๊ฐ€ ๋“ฑ์žฅํ•˜๊ฒŒ ๋œ๋‹ค.

flux
flux

Redux

Redux๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ Flux ํŒจํ„ด์— Reducer๋ฅผ ๋”ํ•ด ๊ตฌํ˜„ํ–ˆ๋‹ค. Redux๋Š” Flux์™€ ๊ฐ™์ด ๋‹จ๋ฐฉํ–ฅ ๋ฐ์ดํ„ฐ ํ๋ฆ„์„ ๊ฐ€์ ธ๊ฐ€๋ฉฐ, ํ•˜๋‚˜์˜ store์— ์ƒํƒœ๋ฅผ ๋ณด๊ด€ํ•˜๊ณ  Reducer๋ฅผ ํ†ตํ•ด ์ „๋‹ฌ๋ฐ›์€ Action์— ๋”ฐ๋ผ ์–ด๋–ป๊ฒŒ ์ƒํƒœ๋ฅผ ์—…๋ฐ์ดํŠธ ํ• ์ง€ ์ฒ˜๋ฆฌํ•œ๋‹ค. ๊ฐ๊ฐ์— ๋Œ€ํ•ด์„œ ์ข€ ๋” ์ž์„ธํžˆ ์ •๋ฆฌํ•ด๋ณด์ž.

redux
redux

  • Action: ์•ก์…˜์€ ์ƒํƒœ์— ์–ด๋–ค ๋ณ€ํ™”๊ฐ€ ํ•„์š”ํ•  ๋•Œ ๋ฐœ์ƒ์‹œํ‚ค๋Š” ๊ฒƒ์œผ๋กœ ์˜ˆ๋ฅผ ๋“ค๋ฉด ๋ฒ„ํŠผ ํด๋ฆญ ์‹œ ์ƒˆ๋กœ์šด Todo๋ฅผ ์ถ”๊ฐ€ํ•˜๊ธฐ ์œ„ํ•ด ๋‹ค์Œ๊ณผ ๊ฐ™์€ Action์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค. ์ฃผ๋กœ Action์„ ๋งŒ๋“ค ๋•Œ ๊ฐ์ฒด ๋‚ด type ์†์„ฑ์ด ๋ฐ˜๋ณต๋˜์„œ ์‚ฌ์šฉ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์•ก์…˜ ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” Action Creator ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•œ๋‹ค.
export function addTodo(data) {
  return {
    type: "ADD_TODO",
    data,
  }
}
  • Reducer: Reducer๋Š” Action๊ณผ ํ˜„์žฌ ์ƒํƒœ๋ฅผ ์ธ์ž๋กœ ๋ฐ›์•„ ์ƒˆ๋กœ์šด ์ƒํƒœ๋กœ ๋ฐ˜ํ™˜ํ•˜๋Š” ์ˆœ์ˆ˜ ํ•จ์ˆ˜๋‹ค. ์ง์ ‘ ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ useState์™€ ๊ฐ™์ด ๋ถˆ๋ณ€์„ฑ์„ ์ง€์ผœ ์ˆ˜์ •๋œ ๋ณต์‚ฌ๋ณธ์œผ๋กœ ์ƒํƒœ๋ฅผ ์—…๋ฐ์ดํŠธ ํ•œ๋‹ค. ์œ„ ์˜ˆ์ œ์˜ "ADD_TODO" action์ด ์ „๋‹ฌ๋˜์—ˆ๋‹ค๋ฉด Todo[]์— ์ƒˆ๋กœ์šด Todo๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๋กœ์ง์„ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋ ‡๊ฒŒ Reducer๋ฅผ ์ž‘์„ฑํ•˜๋‹ค๋ณด๋ฉด ์—„์ฒญ๋‚˜๊ฒŒ ๊ธธ์–ด์งˆ ๊ฒƒ์ด ์˜ˆ์ƒ๋œ๋‹ค. sub-Reducer๋ฅผ ๋งŒ๋“ค์–ด ๊ฐ ๋„๋ฉ”์ธ๋ณ„๋กœ ๊ตฌ๋ถ„ํ•ด์„œ ์ฒ˜๋ฆฌ ๋กœ์ง์„ ์ž‘์„ฑํ•˜๊ณ  Root-reducer๋กœ ํ•ฉ์ณ์„œ ๋ฐ˜์˜ํ•˜๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋‹ค.

    function Todo(state, action) {
    switch (action.type) {
      case "ADD_TODO":
        return [...state, action.data]
      default:
        return state
    }
    }
  • Store: Store๋Š” ํ•˜๋‚˜๋งŒ์„ ๊ฐ€์ง€๊ณ  Reducer๋ฅผ ์ „๋‹ฌํ•ด reducer๋กœ ๋ณ€๊ฒฝ๋œ ์ƒํƒœ๋ฅผ ๋ณด๊ด€ํ•˜๋Š” ์—ญํ• ์„ ํ•œ๋‹ค.

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

๐Ÿ™„ ์ •๋ฆฌํ•˜๋ฉฐ

๋ฆฌ์•กํŠธ ๊ด€๋ จ๋œ ๋ฉด์ ‘ ์งˆ๋ฌธ๋“ค์„ ํ•œ๋ฒˆ์— ์ •๋ฆฌํ•˜๋ฉด์„œ ์—ฌ์ „ํžˆ ๋ชจ๋ฅด๋Š” ์ ์ด ๋งŽ์ง€๋งŒ ํ•ญ์ƒ ๊ธฐ์ˆ ์€ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ๋ฐœ์ „๋˜์—ˆ๋‹ค๋Š” ๊ฒƒ์„ ๋А๋‚„ ์ˆ˜ ์žˆ์—ˆ๋‹ค. ๋ณด๋‹ค ๋ช…ํ™•ํ•˜๊ฒŒ ์ด์•ผ๊ธฐํ•  ์ˆ˜ ์žˆ๊ฒŒ ๊ณ„์†ํ•ด์„œ ์—…๋ฐ์ดํŠธํ•˜๊ณ  ๋‹ค์‹œ ์ž‘์„ฑํ•ด๋‚˜๊ฐˆ ์˜ˆ์ •์ด๋‹ค.

[์ฐธ์กฐ]

@choi2021
๋งค์ผ์˜ ์‹œํ–‰์ฐฉ์˜ค๋ฅผ ๊ธฐ๋กํ•˜๋Š” ๊ฐœ๋ฐœ์ผ์ง€์ž…๋‹ˆ๋‹ค.