main

React와 Vue로 이해하는 단방향, 양방향 데이터 바인딩

Log
13

오늘은 데이터 바인딩의 종류인 단방향 바인딩과 양방향 데이터 바인딩을 예시를 통해 배워볼까합니다.
특히 저는 리액트만 사용해봤어서 양방향 데이터 바인딩에 대해서 감을 잘 못잡고 있었는데요,
오늘 예시를 통해서 제대로 이해해볼까합니다.


데이터 바인딩

먼저 데이터 바인딩이란 무엇일까요?
화면상에 보여지는 데이터(View)와 브라우저 메모리에 있는 데이터(Model)를 묶어서 서로 간의 데이터를 동기화하는 것을 말합니다.

만약에 하나의 쇼핑몰 사이트가 있다고 가정한다면 서버로부터 받아오는 쇼핑목록 데이터를 받아오고 있을텐데요. 예를 들어 옷을 파는 쇼핑몰이라고 했을 때, 아우터, 상의, 바지 등 관련된 항목들을 모두 받아오고 있을 것입니다. 그런데 만약, 쇼핑몰 사장님이 판매하는 새로운 옷을 추가했다면 바뀐 데이터에 맞게 브라우저는 데이터를 받아와 페이지를 새로 그려야합니다.

이처럼 서버 혹은 스크립트상에서 받아온 데이터를 화면상에 그려주고 있다고 가정을 했을 때, 해당 값이 변경이 될 경우 다시 HTML 상에 데이터(값)를 변경된 값에 따라서 맞추어 주는 동작을 '데이터 바인딩'이라고 합니다.


값을 데이터 바인딩하는 예시 (React)

import React, { useState } from 'react';
import { CommonType } from '../../type/common/CommonType';
 
const DataBindingBasicComponent = () => {
 
    /**
     * 브라우져 메모리상에 존재하는 데이터 
     */
    const [initData, setInitData] = useState({
        greet: "안녕하세요",
        info: "데이터 바인딩에 대해서 공부하고 있습니다."
    });
    
    /**
     * 버튼을 클릭하면 상태로 지정한 메모리로 데이터를 바인딩 한다.
     */
    const reDataBinding = () => {
        setInitData({
            greet: "다시 한번 반갑습니다",
            info: "데이터를 바인딩 합니당"
        })
    };
 
    return (
        <div>
            <h1>{initData.greet}</h1>
            <h2>{initData.info}</h2>
            <button onClick={reDataBinding}>재 데이터 바인딩</button>
        </div>
    );
}
 
export default DataBindingBasicComponent;

위의 예제에서 먼저 initData라는 데이터를 초기화된 값으로 HTML상에 출력합니다.
이후, 버튼을 클릭하게 되면 값을 변동시키고 HTML에서 데이터 바인딩을 하는 예시입니다.


CSS 값(스타일)을 데이터 바인딩하는 예시 (React)

import React, { useState } from 'react';
const DataBindingCSSComponent = () => {
 
    /**
     * 브라우져 메모리상에 존재하는 데이터(CSS Style) 
     */
    const [initCSSStyle, setInitCSSStyle] = useState({
        color: "red",
        fontSize: "30"
    });
 
    /**
     * 버튼을 클릭하면 상태로 지정한 메모리로 데이터를 바인딩 한다.
     */
    const reDataBinding = () => {
        setInitCSSStyle({
            color: "yellow",
            fontSize: "50"
        });
    };
    return (
        <div>
            <h1 style={initCSSStyle}>안녕하세요</h1>
            <h2 style={initCSSStyle}>만나서 반갑습니다.</h2>
            <button onClick={reDataBinding}>재 데이터 바인딩</button>
        </div>
    )
}
export default DataBindingCSSComponent;

위 예시에서 initCSSStyle로 초기화 한 스타일을 최초 HTML상에 출력합니다.
이후 버튼을 누르면 상태 값을 변경시키고, HTML에서 데이터 바인딩을 하는 예시입니다.


단방향 데이터란 바인딩 (One-way Data Binding)

단방향 데이터란 자바스크립트에서 HTML로 한 방향으로만 데이터를 동기화하는 것을 말합니다.
즉, 데이터가 Model에서 View로 흐름이 같은 방향으로 흐르게 됩니다.

231016-000519
단방향이기때문에 흐름이 역방향으로 이뤄질 수 없습니다. View -> Model 과같은 흐름이 불가능하다는 것입니다.
컴포넌트 간에서 단방향 데이터 바인딩은 부모 컴포넌트에서 자식 컴포넌트로만 데이터가 전달되는 구조입니다.
리액트를 많이 사용해보신분들은 알다시피 SPA Framework에서는 React에서 단방향 데이터 바인딩을 합니다.

단방향 데이터 바인딩은 리액트의 FLUX 패턴과도 연관이 있습니다. 이전에 많이 사용되었던 MVC패턴 같은 경우 뷰가 많은 프론트엔드에서는 적합하지 않은 패턴이었기 때문에, 데이터의 흐름의 예측이 용이한 FLUX 패턴이 등장하게 되었습니다.
즉, 단방향 데이터 바인딩은 데이터의 흐름을 쉽게 이해할 수 있습니다.

단점으로는 변화를 감지하고 화면을 업데이트 하는 코드를 매번 작성해야 하는 것입니다. 이게 무슨 이야기일까요?
저는 사실 뷰에서 모델로 흐르는 예시를 제대로 이해하지 못하고 있었는데요,
데이터가 뷰에서 모델로 이동할 수 있는 시나리오가 있습니다. 이를 종종 "사용자 입력 처리" 또는 "이벤트 처리"입니다.
사실 단방향 데이터 바인딩에서 아무런 처리가 없다면 원래 사용자 입력처리나 이벤트 처리는 반대로 흐르기 때문에 되지 않아야합니다.
따라서 이런 데이터 변동 흐름을 만들기 위해서 데이터의 변화를 감지하고 매번 화면을 업데이트 하는 코드를 매번 작성해주어야하는 것입니다.

예를 들어, 버튼 클릭 시, 데이터가 변동된다고 가정한다면 버튼만 클릭한다면 아무런 변화가 일어나지 않습니다. 우리가 직접 버튼에 핸들러를 달아주어야지만 데이터 변동이 가능한 것입니다. 리액트에서도 이벤트 핸들러를 각각 모두 달아주어야하는 이유가, 단방향이기때문에 직접 변화를 감지해야해서입니다.

단방향 데이터 바인딩 장단점

  • 장점
    • 데이터의 흐름이 단방향이기 때문에 코드가 이해하기 쉽고 데이터 추적과 디버깅이 쉽다.
    • 데이터 변화에 따른 성능 저하 없이 DOM 객체 갱신이 가능하다.
  • 단점
    • 매번 변화를 감지하고 화면을 업데이트하는 코드를 매번 직접 작성해야한다.

양방향 데이터 바인딩 (Two-way Data Binding)

아까 단방향 데이터는 Model에서 View로만 데이터가 흐를 수 있었는데요, 양방향 데이터는 양쪽에서의 흐름이 모두 가능합니다.
컴포넌트 내에서 Javascript(Model)와 HTML(View) 사이에 ViewModel이 존재하여 하나로 묶여서(Binding) 되어서 둘 중 하나만 변경되어도 함께 변경되는 것을 의미합니다.
231016-002405
컴포넌트 간에서는 부모 컴포넌트에서 자식 컴포넌트로는 Props를 통해 데이터를 전달하고, 자식 컴포넌트에서 부모 컴포넌트로는 Emit Event를 통해서 데이터를 전달하는 구조입니다.
대표적으로 SPA Framework에서는 Vue.js, Angular에서 양방향 데이터 바인딩을 합니다.
231016-002623

저는 리액트만 사용해본 개발자로서 양방향 데이터 바인딩에 대해 개념을 배울 때마다 사실 잘 와닿지 않았습니다.
그래서 오늘은 Vue.js를 사용해서 예시를 알아볼까합니다.


Vue.js로 확인하는 예제

먼저 저는 단방향 데이터 바인딩과 비교해서 양방향 데이터 바인딩은 인풋이나 버튼같은 곳에 핸들러를 달지 않아도 저절로 모델이 변경이 되는 것이라고 가정해보았습니다. 정말일까요?

new Vue({ 
  el: "#app", 
  data: {
    name: "Hoza"
  }
})

vue에서는 useState와 비슷하게 data 객체를 열어서 데이터를 초기화할 수 있습니다. 현재 name은 "Hoza"라고 초기화되어있는 것입니다.

<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<div id="app">
  <input type="text" v-model="name">
  {{ name }}
</div>

HTML에 input태그를 생성하고, v-model 디렉티브를 설정합니다. 여기서 data 객체 내에 name을 생성하고 v-model이 name을 바라보도록 설정해주었습니다.
그다음 input에 입력을 해볼까요?

자, 보이시나요?
input창에서 입력을 하면 v-model 디렉티브를 통해서 Vue의 data를 직접적으로 수정할 수 있는 것을 볼 수 있습니다.
원래 리액트라면 input에 핸들러를 직접적으로 명시해주어야했을텐데 말이죠.😎
{{ name }} 은 단방향 데이터 바인딩으로 Vue 인스턴스가 가지고 있는 정보를 보여주는 역할만을 하는데 input 태그 내의 값을 변경해주자 보여지는 값도 바로 변경되는 것을 확인하실 수 있습니다.

사실 Vue는 리액트처럼 v-on:keyup와 같은 이벤트 핸들러를 달아서 수정이 가능하게도 할 수 있습니다.
예시는 아래에서 확인해주시면 좋을 것 같아요.☺️
5. 데이터 양방향 바인딩 (Data Two Way Binding - v-model)
따라서 Vue.js는 단방향 바인딩과 양방향 바인딩 둘다 지원해주고 있는 것을 알 수 있습니다.


양방향 데이터 바인딩 장단점

  • 장점
    • 코드 사용면에서 코드량을 크게 줄여준다.
    • 매번 코드를 적지않아도 알아서 변화를 감지해준다.
  • 단점
    • 변화에 따라 DOM 객체 전체를 렌더링해주거나 데이터를 바꿔주므로 성능이 감소되는 경우가 있다.

Reference Doc

[React] 데이터 바인딩이란?
단반향 바인딩과 양방향 바인딩
[맨땅에VueJS]양방향 데이터 바인딩 v-model / two way binding / VueJS Directive


김다은 이모지
Daeun Kim
Junior Frontend Engineer