티스토리 뷰
데이터 바인딩(Data Binding)과 MVVM (Vue, React)
UI(View)와 데이터(Model)를 자동으로 연결해주는 기술
즉, 데이터가 바뀌면 UI도 자동으로 바뀌고 UI가 바뀌면 데이터도 자동으로 바뀌는 연결 구조
종류
타입 | 설명 | 예시 |
단방향 바인딩(One-way) | 데이터 -> UI만 반영 | React 기본 방식 (Props) |
양방향 바인딩 (Two-way) | 데이터 <-> UI 상호 반영 | Vuew의 v-model, Angular의 {(ngModel)} |
MVVM (Model-View-ViewModel) 패턴
데이터 바인딩을 체계적으로 적용하기 위한 아키텍쳐 패턴
구성요소 | 역할 |
Model | 실제 데이터 또는 상태 (API 응답, 사용자 정보 등) |
View | 화면(UI) - 사용자에게 보여지는 부분 |
ViewModel | View와 Model 사이에서 데이터 바인딩, 로직 담당(중간다리) |
흐름
Model <----> ViewModel <----> View
- View는 ViewModel에 의존한다. (Model을 모르는 상태)
- ViewModel은 Model을 조작하고, View와 연결한다.
React에서는 MVVM을 쓸까?
전통적인 MVVM 구조는 아니지만, 그에 가까운 구조로 설계할 수는 있다.
하지만 리액트의 철학은 단방향 데이터 흐름이므로 기본적으로 MVVM 구조는 아니다.
핵심의 차이
특징 | MVVM | React |
데이터 흐름 | 양방향 가능 (Tow-way binding) | 단방향 (Parent->Child) |
View-Model 연결 | 자동 바인딩 | 명시적 상태 전달 (Props) |
목적 | 생산성 + 바인딩 편의성 | 상태 예측 가능성, 디버깅 용이성 |
대표 예 | Angular, Vue (초기) | React, Redux 기반 앱 |
리액트의 철학은 단방향 데이터 흐름이다.
function Parent() {
const [name, setName] = useState('John');
return <Child name={name} />;
}
function Child({ name }) {
return <div>{name}</div>;
}
부모가 자식에게 데이터(props)를 단방향으로 전달하는 구조이고, 자식은 상태를 변경할 수 없다. 단지 렌더링만 담당한다.
이 구조는 예측 가능하고 디버깅이 쉬운 구조를 만든다.
하지만 이 말이 곧 'React는 양방향 바인딩이 없을까?' 라고 할 수는 없다.
명시적으로는 구현 할 수 있기 때문이다.
function InputForm(){
const [value, setValue] = useState('');
return <Input value={value} onChange={(e) => setValue(e.target.value)} />;
}
이것도 사실은 양방향 데이터 바인딩 처럼 보이는 단뱡향 데이터 바인딩이다.
value는 상태에서 UI로 흐르고, onChange는 UI에서 상태로 흐름을 명시적으로 구현한 예시이다.
자동 바인딩이 아닌 수동적/명시적 바인딩이다.
예시
React 스타일의 MVVM 구조로 설계해보기
- Model - useState, useQuery, Redux state 등
- ViewModel - custom hooks, container component
- View - presentational component
// Model + ViewModel
function useUserProfile(id){
const { data, isLoading } = useQuery(['user', id], fetchUser);
return { user: data, isLoading };
}
// View
functon UserProfile({ id }) {
const { user, isLoading } = useUserProfile(id);
if(isLoading){
return <Loading />;
}
return <div>{user.name}</div>;
}
Q. 핵심의 차이 > 대표 예에서 Vue (초기) 라고 되어있는 이유 ?
A. Vue 1.x ~ 2.x 초창기 철학은 거의 MVVM 이었다.
<input v-model="username" />
- data -> View에 자동 바인딩
- v-model -> 양방향 데이터 바인딩
- methods, computed -> viewModel 역할
- View는 HTML 템플릿 (template)
- ViewModel은 Vue 컴포넌트 자체 ( new Vue({...}) )
Vue는 3부터 다음과 같은 방향으로 바뀌기 시작했다.
변화 | 설명 |
Composition API 도입 | MVVM의 ViewModel 중심 구조에서 벗어나 로직 중심 재사용 강조 |
Typescript 강화 | 명시적 타입 추론과 관리 -> 더 함수형 적인 접근 |
Reactivity 명시화 | reactive(), ref() 등 -> 반응형을 수동으로 제어 |
자동 양방향 바인딩 탈피 가능 | v-model도 내부적으로는 :value + @input 조합임을 명확화 |
즉, Vue 3에서는 MVVM보다는 구성 가능하고, 명시적인 상태 관리가 중심이 됨
시기 | 스타일 | 이유 |
Vue 1.x~2.x | MVVM | 컴포넌트가 ViewModel, 자동바인딩 중심 |
Vue 3.x 이후 | Composition / 함수형 구조 | 명시적 상태, 유연한 아키텍처 중심 (React와 유사해짐) |
그래서 요즘 Vue는
- v-model도 명시적으로 커스터마이징 가능
- setup() 기반으로 ViewModel -> logic module 분리
- 점점 MVVM보다는 Composition 중심 패턴으로 가고 있다.
Q. Vue3에서 v-model 더 명시적으로 커스터마이징 가능하다면, 안쓸수도 있는건가? 리액트와 같은 단방향 흐름으로 말이야. 그리고 이게 Vue3가 추구하는 철할이야?
A. Vue 3의 철학은 '선택의 유연성이다' (중립적 유연)
Vue 3는 MVVM 방식도 가능하고 리액트와 같이 '명시적 단방향 흐름'도 가능하다.
Vue 3의 철학의 핵심은 'Composition'과 유연함이다.
즉, '개발자에게 선택지를 주되, 예측 가능성과 컴포넌트 구성 유연성을 보장하자'라는 방향을 지향한다.
핵심 변화 | 설명 |
Composition API | setup() 을 중심으로 로직을 조합하고 분리할 수 있게 한다. |
명시적 반응성 제어 | ref, reactive 등을 통해 상태 흐름을 더 명확하게 함 |
옵션 API <-> Composition API 공존 | 개발자의 스타일에 따라 선택 가능하게 만듦 |
자동화 <-> 명시화 공존 | v-model도 쓰고, 직접 @input + :value 조합도 가능하다. |
그렇다고 해서 v-model이 지양되는건 아니다.
여전히 폼 바인딩, 간단한 컴포넌트 연동, 커스텀 컴포넌트 v-model 등에선 아주 유용하게 쓰이고 있다.
단지 React 처럼 명시적인 구조를 선호하는 사람을 위해 우회로도 열어준 것 뿐이다.
예시
Vue에서 v-model 없이 React와 같이 개발
<script setup>
import { ref } from 'vue';
const message = ref('');
const updateMessage = (e) => {
message.value = e.target.value;
};
</script>
<template>
<input :value="message" @input="updateMessage" />
</template>
React 처럼 value + onChange 방식으로 명시적 구현
v-model이 자동화해주는 걸 수동으로 직접 컨트롤하는 React 식 데이터 바인딩
Vue(MVVM 스타일) VS React(단방향 흐름) 구조 비교
항목 | Vue (MVVM) | React (단방향 흐름) |
바인딩 방식 | 양방향 (v-model) | 단방향 (value + onDhange) |
구조 철학 | 선언적 + 자동연결 | 명시적 상태 흐름 |
View <-> Model 연결 | 자동화 | 수동으로 명시 |
초기 학습 곡선 | 더 쉬움 (간단한 코드) | 구조 이해가 필요 |
상태 추적/디버깅 | 바인딩이 숨겨져 있어 디버깅 어려울 수 있다. | 상태 흐름이 명확해서 추적이 쉽다. |
컴포넌트 재사용성 | 내부 상태 숨기기 쉬워서 때로는 낮음 | 상태 주입이 명확해서 재사용 용이 |
복잡한 폼 처리 | 적은 코드로 빠르게 구성 | 명시적이지만 코드량이 많아질 수 있다. |
권장되는 흐름 | 간단한 앱엔 좋지만, 점점 Composition 중심 | 일관된 단방향 흐름 유지 강조 |
'개념 > 2025 학습' 카테고리의 다른 글
클라이언트에서 API 호출할때 사용하는 도구를 알아보자. (fetch, axios, TanStack Query, SWR) + graphql, firebase, supabase (0) | 2025.04.10 |
---|---|
프로젝트에서 Vue 쓸까? React 쓸까? (0) | 2025.04.06 |
자바스크립트 쓰로틀링(Throttling), 디바운싱(Debouncing) 성능 최적화 (0) | 2025.04.06 |
브라우저, Node.js의 이벤트 루프와 차이 (0) | 2025.04.02 |
가상돔(Virtual DOM)과 React Fiber 구조 (0) | 2025.03.26 |
이벤트 루프와 Web APIs의 관계 (0) | 2025.03.06 |
이벤트 위임(Event Delegation)과 성능 최적화 (0) | 2025.02.27 |
프로토타입과 프로토타입 체인 (0) | 2025.02.25 |