props는 부모 -> 자식 방향으로 단방향의 데이터 흐름을 갖는다. 이 말은 최초 데이터를 발생시킨 부모가 값을 변경시키면 이 값을 props로 받은 모든 자식들의 값이 변경된다. 하지만 자식이 전달받은 props 값을 변경했다고 부모의 값이 변경되지는 않는다.
만약 자식 1이 전달받은 props를 변경했을 때 부모의 값이 변경돼버린다면 자식 2나 3도 영향을 받아버리니까 엄청난 혼선이 올 것이다.
props는 readonly로 사용하자!
그럼 어차피 전달받은 props는 자식꺼니까 자식이 마음대로 변경해서 사용해도 괜찮을까? 이것도 역시 아니다. 자식이 props로 열심히 연산을 하다가 부모가 새로운 값을 던져줘 버리면 이제까지 자식이 하던 일은 말짱 헛 일이 된다.
따라서 props의 값은 readonly로 사용하는 것이 좋다. 하지만 문제는 그냥 props를 편집해 보면 경고는 나오지만 된다는 점이다. 강제할 수는 없다.
하지만 v-model 영역에서는 props의 값을 할당하기만 해도 오류가 발생하면서 컴파일이 되지 않는다.
props를 readonly로 강제하려면?
하지만 프로그래밍을 하다 보면 props를 변경하는 실수를 하는 경우가 많다. 이 실수를 방지하기 위해서 크게 2가지 방법을 사용할 수 있다.
props로 전달된 값을 로컬 데이터에 할당해서 사용한다. 그럼 로컬 데이터를 변경하는데 문제없고 부모와의 관계도 없어진다. 만약 전달받은 props가 객체형일 때에는 deep copy 해서 사용해야 한다. 이때 단점은 부모가 변경되었을 때 자식이 그 상황을 파악하지 못한다.
// 지역 변수에 할당해서 사용하기
const localNum2 = ref(props.num2);
const localObj = reactive({...props.obj});
두 번째 방법은 단순한 로컬 데이터에 저장하지 않고 computed 속성으로 정의하는 것이다. computed는 관련 데이터가 변경되면 자동으로 변경되는 특성이 있기 때문에 부모가 변경되었을 때 자식도 변경되고, computed는 readonly이기 때문에 값을 수정하려는 경우 오류가 발생한다.
// computed로 사용하기
const computedNum3 = computed(()=>props.num3)