# 🀹🏻 ν”„λ‘ νŠΈμ—”λ“œ μƒνƒœκ΄€λ¦¬

# πŸ§‘πŸΌβ€πŸš€ μƒνƒœ 관리λ₯Ό μ•Œμ•„μ•Ό ν•˜λŠ” 이유

❗데이터가 λ³€ν•  λ•Œλ§ˆλ‹€ 데이터에 κ΄€λ ¨λœ dom을 일일히 μ°Ύμ•„μ„œ μ‘°μž‘ν•˜κ³  싢지 μ•Šλ‹€λ©΄ ❗전체 λ°μ΄ν„°μ˜ ν˜•νƒœμ™€ 리슀트λ₯Ό ν•œ κ³³μ—μ„œ 효율적으둜 κ΄€λ¦¬ν•˜κ³  μ‹Άλ‹€λ©΄

# πŸ”₯ μƒνƒœλž€

ν”„λ‘ νŠΈμ—”λ“œ ν”„λ‘œκ·Έλž˜λ°μ„ ν•˜λ©΄μ„œ μƒνƒœ(state)κ΄€λ¦¬λΌλŠ” μš©μ–΄λ₯Ό 많이 μ“°λŠ”λ°μš”. μƒνƒœλž€ μ‰½κ²Œ λ§ν•˜λ©΄ '데이터' 라고 μƒκ°ν•˜λ©΄ 쒋을 것 κ°™μŠ΅λ‹ˆλ‹€. 이 μƒνƒœ κ΄€λ¦¬λŠ” μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜μ΄ λ³΅μž‘ν•΄μ§ˆμˆ˜λ‘ 점점 μ–΄λ €μ›Œμ§‘λ‹ˆλ‹€. κ·Έλ ‡κΈ° λ•Œλ¬Έμ— λ‹¨μˆœν•œ κ΅¬μ‘°μΌλ•ŒλΆ€ν„° 이 μƒνƒœλ₯Ό μ–΄λ–»κ²Œ κ΄€λ¦¬ν•˜λ©΄ 쒋을지에 λŒ€ν•œ 고민을 μΆ©λΆ„νžˆ ν•΄λ³΄λŠ” 것은 더 큰 μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜μ„ λ§Œλ“€κΈ° μœ„ν•œ κ³Όμ •μ—μ„œ μ€‘μš”ν•©λ‹ˆλ‹€.

λ¨Όμ € μƒνƒœλž€ λ¬΄μ—‡μΌκΉŒμš”? μƒνƒœκ°€ 있고, μƒνƒœκ°€ μ•„λ‹Œ 것이 μžˆμ„ν…λ°μš”. λ‘˜μ€ μ–΄λ–€ 차이가 μžˆμ„κΉŒμš”? μƒνƒœμ—μ„œ μ€‘μš”ν•œ 뢀뢄은 λ°”λ‘œ 값이 λ³€ν•œλ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€. 이 값이 λ³€ν•˜λŠ”λ° 예츑된 κ°’μœΌλ‘œ λ³€ν•΄μ•Ό μ˜λ„ν•œλŒ€λ‘œ λ™μž‘μ„ μˆ˜ν–‰ν•  수 μžˆμœΌλ‹ˆ, 예츑 λ²”μœ„ μ•ˆμ—μ„œ λ³€ν•˜κ²Œ ν•˜λŠ” 것이 μ€‘μš”ν•©λ‹ˆλ‹€. κ·Έλž˜μ„œ κ·Έ 예츑된 λ²”μœ„λ₯Ό λ§Œλ“€κΈ° μœ„ν•΄μ„œ, μ—¬λŸ¬κ°€μ§€ μ œμ•½μ‘°κ±΄μ΄λ‚˜ ꡬ쑰적인 섀계λ₯Ό κ³ λ―Όν•  수 μžˆμŠ΅λ‹ˆλ‹€.

이 예츑 λ²”μœ„λ₯Ό μ΅œμ†Œν™” ν•˜κΈ° μœ„ν•΄μ„œλŠ” μƒνƒœμ— λŒ€ν•΄ μΌκ΄€λ˜κ²Œ READν•˜λŠ” 둜직과, μ΅œμ†Œν™”ν•œ Writeν•˜λŠ” λ‘œμ§μ„ λ§Œλ“€ λ•Œ κ°€λŠ₯ν•΄μ§‘λ‹ˆλ‹€.

λ²”μœ„λ₯Ό μ΅œμ†Œν™”ν•˜λŠ”κ±°λŠ” λͺ¨λ“ˆ λ‹¨μœ„, μŠ€μ½”ν”„ λ‹¨μœ„μ— λŒ€ν•œ 고민으둜 ν™•μž₯될 수 μžˆμŠ΅λ‹ˆλ‹€. μƒνƒœμ— λŒ€ν•œ 일관성은 μƒνƒœλ₯Ό μ—¬λŸ¬ κ³³μ—μ„œ 같은 λ°©μ‹μœΌλ‘œ READν•˜λŠ” 방식을 κ³ λ―Όν•΄λ³Ό 수 μžˆμŠ΅λ‹ˆλ‹€. μƒνƒœλ₯Ό μ—¬λŸ¬ κ³³μ—μ„œ μ§μ ‘μ μœΌλ‘œ μˆ˜μ •ν•œλ‹€λ©΄, μƒνƒœλ₯Ό μ˜ˆμΈ‘ν•˜κ³  κ΄€λ¦¬ν•˜κΈ° μ–΄λ €μš°λ‹ˆ μˆ˜μ •ν•˜λŠ” 뢀뢄을 μ œν•œν•˜κ³ , κ·Έ μ±…μž„μ„ 가지고 μžˆλŠ” λŒ€μƒμ΄ λΆ„λͺ…ν•˜κ²Œ 역할을 가진닀면 μ΅œμ†Œν™”ν•œ writeκ°€ κ°€λŠ₯ν•΄μ§ˆ 수 μžˆμŠ΅λ‹ˆλ‹€.

ν”„λ‘ νŠΈμ—”λ“œμ˜ μƒνƒœ 관리λ₯Ό Todo Listλ₯Ό ν†΅ν•΄μ„œ μ–΄λ–»κ²Œ ν•  수 μžˆμ„μ§€ κ³ λ―Όν•΄λ³΄κ² μŠ΅λ‹ˆλ‹€.

image.png

μœ„ TodoList 앱은 TodoItemsλΌλŠ” 데이터 값을 κ°€μ§‘λ‹ˆλ‹€. 그런데 이 데이터λ₯Ό μ—¬λŸ¬κ΅°λ°μ—μ„œ κ΄€λ¦¬ν•œλ‹€λ©΄ ν•œ 곳에 λ³€ν™”κ°€ μžˆμ„ λ•Œλ§ˆλ‹€, λͺ¨λ“  λ³€ν™”λ₯Ό κ°μ§€ν•˜κ³  λ°˜μ˜ν•˜λ €λ©΄ 쀑볡 μ½”λ“œλ„ λ§Žμ•„μ§€κ³  λΆˆν•„μš”ν•œ dom μ ‘κ·Ό λ˜ν•œ λ§Žμ•„μ§ˆ 수 μžˆμŠ΅λ‹ˆλ‹€. κ·Έλ ‡λ‹€λ©΄ 이 데이터λ₯Ό μ–΄λ–»κ²Œ, μ–΄λ””μ„œ κ΄€λ¦¬ν•˜λ©΄ μ’‹μ„κΉŒμš”?

μš°μ„  데이터와 κ΄€λ ¨λœ 뢀뢄듀을 μ²΄ν¬ν•˜κΈ° μœ„ν•΄ μ•žμ˜ λ¬Έμ„œμ—μ„œ λ³΄μ•˜λ˜ κ²ƒμ²˜λŸΌ 데이터λ₯Ό 가지고 κ°±μ‹ λ˜μ•Ό ν•˜λŠ” κΈ°μ€€μœΌλ‘œ UIλ₯Ό λΆ„λ¦¬ν•΄λ³΄κ² μŠ΅λ‹ˆλ‹€.

image.png

더 μ„ΈλΆ€μ μœΌλ‘œ 뢄리할 수 도 μžˆμ§€λ§Œ, μš°μ„ μ€ 이 4κ°€μ§€λ‘œ λΆ„λ¦¬ν•΄λ³Όκ±΄λ°μš”. μœ„μ²˜λŸΌ κ΅¬λΆ„ν•˜κ³  λ‚˜λ©΄, TodoAppμ΄λΌλŠ” μ»΄ν¬λ„ŒνŠΈ μ•ˆμ— TodoInput, TodoList, TodoCount UI듀이 ν¬ν•¨λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€.


μ»΄ν¬λ„ŒνŠΈλ₯Ό 더 μ„ΈλΆ€μ μœΌλ‘œ 뢄리할 수 도 μžˆμ§€λ§Œ, μš°μ„ μ€ 이 4κ°€μ§€λ‘œ μ»΄ν¬λ„ŒνŠΈλ₯Ό 뢄리해보도둝 ν•˜κ² μŠ΅λ‹ˆλ‹€, μœ„μ²˜λŸΌ κ΅¬λΆ„ν•˜κ³  λ‚˜λ©΄, TodoAppμ΄λΌλŠ” μ»΄ν¬λ„ŒνŠΈ μ•ˆμ— TodoInput, TodoList, TodoCount μ»΄ν¬λ„ŒνŠΈλ“€μ΄ ν¬ν•¨λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€. 그리고 TodoItemsλΌλŠ” λ°μ΄ν„°λŠ” TodoInput, TodoList, TodoCount 3개의 μ»΄ν¬λ„ŒνŠΈμ™€ λͺ¨λ‘ 관련이 μžˆλŠ”λ°μš”. κ·Έλ ‡λ‹€λ©΄ TodoItems와 연결성을 가진 이 데이터λ₯Ό μ–΄λ””μ„œ κ΄€λ¦¬ν•˜λ©΄ μ’‹μ„κΉŒμš”? μœ„μ—μ„œ writeλŠ” μ΅œμ†Œν•œμœΌλ‘œ 역할을 λΆ€μ—¬ν•˜λ©΄ μ’‹λ‹€κ³  ν–ˆλŠ”λ°μš”. κ·Έλ ‡λ‹€λ©΄ 이 μƒνƒœμ—μ„œ 데이터λ₯Ό ν•œ κ³³μ—μ„œ κ΄€λ¦¬ν•œλ‹€λ©΄ TodoApp μ»΄ν¬λ„ŒνŠΈμ—μ„œ ν•˜κ³ , λ‹€λ₯Έ μ»΄ν¬λ„ŒνŠΈλ“€μ€ κ·Έ 데이터λ₯Ό λ°›μ•„μ™€μ„œ λ³΄μ—¬μ£ΌκΈ°λ§Œ ν•œλ‹€λ©΄ 데이터λ₯Ό μΌκ΄€λ˜κ²Œ 관리할 수 μžˆμ„ 것 κ°™μŠ΅λ‹ˆλ‹€.

image.png

κ·Έλž˜μ„œ 기본적으둜 κ΅¬ν˜„ν•˜κΈ°μ— κ°„λ‹¨ν•œ ꡬ쑰가 μžˆμŠ΅λ‹ˆλ‹€. λ°”λ‘œ setState와 renderν•¨μˆ˜μ˜ κ΅¬ν˜„μž…λ‹ˆλ‹€.

# πŸ“Œ setState & πŸ–ŒοΈ render

input창에 todoItem을 μƒˆλ‘œ μΆ”κ°€ν•œλ‹€κ³  ν–ˆμ„ λ•Œ, κ·Έ μΆ”κ°€ν•˜λŠ” λ©”μ„œλ“œλ₯Ό λΆ€λͺ¨ μ»΄ν¬λ„ŒνŠΈμ—μ„œ κ΄€λ¦¬ν•˜κ³ , μžμ‹ μ»΄ν¬λ„ŒνŠΈλŠ” λΆ€λͺ¨ μ»΄ν¬λ„ŒνŠΈκ°€ 데이터λ₯Ό 직접 λ‹€λ£¨λŠ” λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•˜κΈ°λ§Œ ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€.

// λΆ€λͺ¨ μ»΄ν¬λ„ŒνŠΈ
function TodoApp() {
  this.todoItems = [];

  this.setState = updatedItems => {
    this.todoItems = updatedItems;
    todoList.setState(this.todoItems);
  };

  new TodoInput({
    onAdd: contents => {
      const newTodoItem = new TodoItem(contents);
      this.todoItems.push(newTodoItem);
      this.setState(this.todoItems);
    }
  });
}

// μž…λ ₯ λ°›λŠ” μ»΄ν¬λ„ŒνŠΈ
function TodoInput({ onAdd }) {
  const $todoInput = document.querySelector("#new-todo-title");

  $todoInput.addEventListener("keydown", event => this.addTodoItem(event));

  this.addTodoItem = event => {
    const $newTodoTarget = event.target;
    if (this.isValid(event, $newTodoTarget.value)) {
      onAdd($newTodoTarget.value);
      $newTodoTarget.value = "";
    }
  };
}

// todoList λ³΄μ—¬μ£ΌλŠ” μ»΄ν¬λ„ŒνŠΈ
function TodoList() {
  this.setState = updatedTodoItems => {
    this.todoItems = updatedTodoItems;
    this.render(this.todoItems);
  };

  this.render = items => {
    const template = items.map(todoItemTemplate);
    this.$todoList.innerHTML = template.join("");
  };
}

μ΄λ ‡κ²Œ ν•˜λ©΄, 데이터λ₯Ό ν•œ κ³³μ—μ„œ 효율적으둜 관리할 수 있고 데이터가 λ³€κ²½λ˜μ—ˆμ„ λ•Œ λ Œλ”λ§μ„ μƒˆλ‘œ ν•΄μ£ΌλŠ” λ‘œμ§λ„ μž¬μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

# πŸ“˜ 정리

  • ν”„λ‘ νŠΈμ—”λ“œμ—μ„œ μƒνƒœκ΄€λ¦¬λŠ” ν•œ κ³³μ—μ„œ ν•˜λ©΄ 효율적으둜 ν•  수 μžˆλ‹€.
  • 보톡은 μ΅œμƒμœ„ μ»΄ν¬λ„ŒνŠΈλ‚˜, storageλ₯Ό λ”°λ‘œ 두어 κ΄€λ¦¬ν•œλ‹€.
  • μžμ‹ μ»΄ν¬λ„ŒνŠΈλ“€μ€ μ΅œμƒμœ„ μƒνƒœλ₯Ό 가지고 μžˆλŠ” κ°μ²΄λ‘œλΆ€ν„° μƒνƒœλ₯Ό λ°›μ•„ renderν•΄μ£ΌλŠ” 역할을 ν•œλ‹€.