# 14. Todo - Update (Text)

## 목표

선택된 Todo 의 텍스트를 업데이트합니다.

### 실습

앞서했던 상태 업데이트와 비슷합니다.\
li 에 editing 이라는 class 가 추가되면 해당 Todo 에 숨겨져있던 input 이 나옵니다.\
우리는 Todo 가 더블클릭 되었을때 이처럼 변하길 원합니다.

![](/files/-LjLfIbRYANG9KVSeAc9)

먼저 App.vue 에 변화되는 text 와 id 를 받아 텍스트를 업데이트하는 함수를 만들어보겠습니다.

```javascript
// App.vue 

export default {
  // ... 
  methods: {
    insertTodo(text) { // ... },
    removeTodo(id) { // ... },
    updateDone(id) { // ... },
    updateTodo({ id, text }) {
      const todos = [...this.todos];
      const todo = todos.find(todo => todo.id === id);

      if (todo) {
        todo.text = text;
        this.todos = todos;
      }
    }
  }
};
```

id 와 text 를 받아 해당 todo 를 찾아 text 를 업데이트합니다.\
마찬가지로 Todo.vue 에서 사용될 함수이기 때문에 아래와 같이 이벤트를 등록해줍니다.

```javascript
// App.vue 

<template>
  <div id="app">
    <section class="todoapp">
      <Header @insertTodo="insertTodo" />
      <Todo
        :todos="todos"
        @removeTodo="removeTodo"
        @updateDone="updateDone"
        @updateTodo="updateTodo"
      />
      <Footer />
    </section>
  </div>
</template>
```

이제 Todo.vue 로 넘어가겠습니다.\
Update 에 대한 모든 정보는 Todo.vue 에서 관리되어집니다. 다른 컴포넌트에서는 Edit 상태에 대한 정보가 전혀 궁금하지 않기 때문입니다.

먼저 Todo.vue 에 edit 데이터를 관리하기 위해 edit state 를 추가합니다.\
수정하고 싶은 Todo 가 선택된다면 이 edit state 에 선택된 todo 의 id 와 text 가 채워집니다.\
text 를 따로 관리하는 이유는 기존 데이터와 독립되게 만들기 위해서입니다.\
수정 취소시 원본 데이터는 손상되면 안되기 때문입니다.

```javascript
// Todo.vue

<script>
export default {
  props: {
    todos: { type: Array, default: () => [] }
  },
  data() {
    return {
      edit: { // edit 데이터를 관리합니다.
        text: "",
        id: -1
      }
    };
  },
  methods: {
   // ...
  }
};
</script>
```

이제 더블 클릭 했을때 해당 todo 로 edit 데이터를 채워보겠습니다.

```javascript
// Todo.vue 

<script>
export default {
  props: {
    todos: { type: Array, default: () => [] }
  },
  data() { // ... },
  methods: {
    handleRemove(id) { // ... },
    handleDone(id) { // ... },
    handleEdit({ text, id }) {
      this.edit = {
        text,
        id
      };
    }
  }
};
</script>
```

handleEdit 는 더블 클릭시 선택된 Todo 의 정보를 받아 edit state 를 채우는 함수입니다.

```javascript
// Todo.vue 

<template>
  <section class="main">
    <ul class="todo-list">
      <li
        :class="{todo: true, completed: isDone, editing: edit.id === id }"
        v-for="({ id, text, isDone }) in todos"
        :key="id"
      >
        <div class="view">
          <input class="toggle" type="checkbox" :checked="isDone" @click="handleDone(id)" />
          <label @dblclick="handleEdit({ text, id })">{{ text }}</label>
          <button class="destroy" @click="handleRemove(id)"></button>
        </div>
        <input class="edit" type="text" v-model="edit.text" />
      </li>
    </ul>
  </section>
</template>
```

li 에 editing 이라는 class 조건이 추가되었습니다. edit state 에 있는 id 와 해당 todo 의 id 가 같을때만 input 으로 변경됩니다.\
\
label 이 더블클릭 되었을때 해당 handleEdit 함수를 이용하여 edit state 를 업데이트합니다.\
\
input 은 v-model 을 이용하여 edit state 의 text 를 바라봅니다.\
\
여기까지하셨다면 아래와 같이 더블클릭 했을때 input 으로 변경되어지고 선택된 todo 의 내용으로 input 이 채워지게됩니다.

![](/files/-LjLjJum6vk6YB-GCDFi)

이제 input 에 수정될 값을 입력하고 엔터를 쳤을때 해당 Todo 의 내용이 변경되는 처리만 해주면 됩니다.\
input 에 keypress 이벤트를 걸어주고 엔터가 입력될 경우를 캐치하여 edit state 를 App.vue 에서 등록해둔 이벤트를 실행시켜주면 됩니다.

```javascript
// Todo.vue

<template>
  <section class="main">
    <ul class="todo-list">
      <li
        :class="{todo: true, completed: isDone, editing: edit.id === id }"
        v-for="({ id, text, isDone }) in todos"
        :key="id"
      >
        <div class="view">
          <input class="toggle" type="checkbox" :checked="isDone" @click="handleDone(id)" />
          <label @dblclick="handleEdit({ text, id })">{{ text }}</label>
          <button class="destroy" @click="handleRemove(id)"></button>
        </div>
        <input class="edit" type="text" v-model="edit.text" @keypress="handleUpdate" />
      </li>
    </ul>
  </section>
</template>

<script>
export default {
  props: {
    todos: { type: Array, default: () => [] }
  },
  data() { // ... },
  methods: {
    handleRemove(id) { // ... },
    handleDone(id) { // ... },
    handleEdit({ text, id }) { // ... },
    handleUpdate({ keyCode }) {
      if (keyCode === 13) {
        this.$emit("updateTodo", this.edit);
        this.edit = { // 추가된 후 edit state 를 리셋합니다
          text: "",
          id: -1
        };
      }
    }
  }
}
</script>
```

아래와 같이 수정되는 것을 확인 할 수 있습니다.

![](/files/-LjLkw-FNed3mXAJ2Wez)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://simplevue.gitbook.io/intro/14.-todo-update-text.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
