본문 바로가기

Vue.js

[Udemy Vue 완벽가이드 Section8] 94. props 작동 방식 및 props 변경하기

props는 매우 중요하다.

부모-자식간의 통신에서 props가 사용된다.

 

<!--App.vue-->
<friend-contact
  name="Manuel Lorenz"
  phone-number="01234 78992"
  email-address="manuel@localhost.com"
></friend-contact>

- 위 코드에서 부모 컴포넌트는 App.vue(메인 앱)이 된다. 부모 컴포넌트(App.vue)는 자식 컴포넌트(friend-contact 컴포넌트)와 communicate를 한다.

- friend-contact 컴포넌트는 App.vue의 자식 컴포넌트이다. 왜냐하면 App.vue의 템플릿 내부에서 사용하므로.

- friend-contact 컴포넌트 입장에서 보면 App.vue가 부모가 된다.

이게 바로 부모-자식 개념.

- 부모 ⇒ 자식으로 통신할 때 props를 사용한다. 부모 ⇒ 자식 컴포넌트로 data를 전달하기 위해. 여기선 App.vue에서 friend-contact 컴포넌트로 전달.

 

 

# props는 불변

- 기억해둬야 할 props의 특징이 하나 있다. 바로 props는 불변한다.

 

예를 들어보자.

App.vue에서 friend-contact 컴포넌트로 전달할 "is-favorite" props를 추가해보자.

값으로는 참이면 1, 거짓이면 0을 전달한다고 해보자.

<friend-contact
  name="Manuel Lorenz"
  phone-number="01234 78992"
  email-address="manuel@localhost.com"
  is-favorite="1"
></friend-contact>
<friend-contact
  name="Julie Johns"
  phone-number="01234 78992"
  email-address="manuel@localhost.com"
  is-favorite="0"
></friend-contact>

 

새로운 props를 만들었으니, FriendContact.vue에도 추가해주자.

props: ["name", "phoneNumber", "emailAddress", "isFavorite"],

 

"isFavorite" props로 name 뒤에 추가 정보로 출력해보자.

<h2>{{ name }} {{ isFavorite === '1' ? '(Favorite)' : '' }}</h2>

 

isFavorite 상태를 변경하는 toggleFavorte 메서드로 버튼을 추가해보자.

<button @click="toggleFavorite">Toggle Favorite</button>
methods: {
    toggleFavorite() {
      if (this.isFavorite === "1") {
        this.isFavorite = "0"; //props로 받은 isFavorite값 변경
      } else {
        this.isFavorite = "1"; //props로 받은 isFavorite값 변경
      }
    },
  },

 

이렇게 props로 전달받은 isFavorite 값을 변경하려고 하면, 아래와 같이 "isFavorite prop에 예상치 못한 변경이 발생했다"고 에러가 뜬다. (method를 추가하고 저장만 해도 바로 이런 에러가 뜬다.)

 

즉, props는 불변해야 한다.

 

 

# 왜 props를 변경하면 안되는걸까?

Vue는 단방향 데이터 플로우(Unidirectional data flow) 개념을 사용하기 때문.

어려운 용어 같지만, 뜻은 아주 간단하다.

App.vue(부모 컴포넌트) ⇒ friend-contact(자식 컴포넌트)로 전달되는 데이터는 App.vue(부모 컴포넌트)에서만 변경된다. friend-contact(자식 컴포넌트)에서는 변경이 불가능하다.

그래서 friend-contact에 있는 isFavorite 데이터를 변경하려고 해도, Vue가 그 변경을 허용하지 않는다. 왜냐하면 단방향 데이터 플로우를 위배하는 것이므로.

 

# props를 변경하는 방법

props를 전달받은 컴포넌트에서 props를 변경하고 싶다면, 두 가지 방법을 사용할 수 있다.

 

1/ 부모에게 변경하고 싶다고 알리기.

그러면 부모가 자체적으로 데이터를 변경하고 friend-contact로 업데이트된 데이터를 돌려보낸다.

 

2/ 전달받은 props를 friend-contact 컴포넌트 내부의 초기 data로 취급하기.

다만, 변경사항은 friend-contact에만 적용되고, App.vue에는 변경된 데이터가 반영되지 않는다.

이 패턴을 구현하려면 컴포넌트에 새 data 프로퍼티를 추가한다.

 

새 data 프로퍼티는 props인 isFavorite과는 다른 이름으로 하고, 값을 this.isFavorite으로 설정한다.

props: ["name", "phoneNumber", "emailAddress", "isFavorite"],
  data() {
    return {
      friendIsFavorite: this.isFavorite;
    };
  },

 

그리고 template, methods에 isFavorite 대신, friendIsFavorite으로 변경하자.

<h2>{{ name }} {{ friendIsFavorite === '1' ? '(Favorite)' : '' }}</h2>
methods: {
    toggleFavorite() {
      if (this.friendIsFavorite === "1") {
        this.friendIsFavorite = "0";
      } else {
        this.friendIsFavorite = "1";
      }
    },
  },

이제 오류가 발생하지 않는다.

 

 

props에서 단방향 데이터 플로우는 아주 중요한 개념이다.

 

** 출처: 모든 내용은 Udemy Vue-완벽가이드 강의를 기반으로 작성하였습니다.