Skip to content

React.js vs Vue.js

FoRA edited this page Dec 8, 2020 · 1 revision

Reference from here

JavaScript의 대표적인 라이브러리 2개를 비교해보자! (Angular는 일단 저리 가봐. 2는 또 뭐야)

  • Clipping {숫자} 는 어느 출처에서 글을 가져왔는지를 나타냅니다.
  • 다 읽기 귀찮다면 밑의 정리하자면을 찾아주세요.

React.js

다음의 글은 Clipping 2에서 가져옴.

React는 Facebook에서 개발해 Facebook과 Instagram, Airbnb 등에서 사용하고 있는 오픈소스 UI 프레임워크이다.

사용자 액션에 따라 DOM을 일일이 다루었던 과거 개발 방식(jQuery와 같은 라이브러리만을 사용하는)과는 달리 개발자가 DOM을 직접 다루지 않고 React가 데이터 상태에 따라 자동으로 UI를 관리하기 때문에, 개발자는 단순히 특정 상태에 대한 뷰의 변화만 구현하면 된다.

React는 다음의 세 가지 특징을 갖고 있다.

  • UI 컴포넌트를 만들기 위한 라이브러리이며 React의 컴포넌트는 트리형태로 구성된다.
  • Virtual DOM을 사용하여 변경된 부분에 대한 최소한의 DOM 처리로 UI를 업데이트하여 애플리케이션의 성능을 향상한다.
  • 부모 컴포넌트에서 하위 컴포넌트로 전달하는 단방향의 단순한 데이터 흐름을 갖고 있어 데이터 추적과 디버깅을 쉽게 해준다.

잘 이해가 안되서 한글 공식 사이트에서 찾아 보았다(from Clipping 1).

선언형

React는 상호작용이 많은 UI를 만들 때 생기는 어려움을 줄여줍니다. 애플리케이션의 각 상태에 대한 간단한 뷰만 설계하세요. 그럼 React는 데이터가 변경됨에 따라 적절한 컴포넌트만 효율적으로 갱신하고 렌더링합니다.


선언형 뷰는 코드를 예측 가능하고 디버그하기 쉽게 만들어 줍니다.

컴포넌트 기반

스스로 상태를 관리하는 캡슐화된 컴포넌트를 만드세요. 그리고 이를 조합해 복잡한 UI를 만들어보세요.

컴포넌트 로직은 템플릿이 아닌 JavaScript로 작성됩니다. 따라서 다양한 형식의 데이터를 앱 안에서 손쉽게 전달할 수 있고, DOM과는 별개로 상태를 관리할 수 있습니다.

한 번 배워서 어디서나 사용하기

기술 스택의 나머지 부분에는 관여하지 않기 때문에, 기존 코드를 다시 작성하지 않고도 React의 새로운 기능을 이용해 개발할 수 있습니다.

React는 Node 서버에서 렌더링을 할 수도 있고, React Native를 이용하면 모바일 앱도 만들 수 있습니다.

JSX

from Clipping 3

JSX는 React를 위해 태어난 새로운 자바스크립트 문법으로, 과거 페이스북이 만들었던 PHP의 개량판 XHP에 그 기원을 두고 있습니다. React.js Conf 2015 Keynote

JSX는 보통 선언적이라고 번역되는, Declarative한 개발을 도와주는 도구입니다. 간단하게 말해 한눈에 이해하기 쉬운 개발을 만들어 줍니다. JSX는 그 형태가 마치 html과 같습니다. 유저에게 보여주고 싶은 최종적인 View라고 할 수 있죠. 개발자는 JSX를 통해 결과물에 직관적으로 도달할 수 있습니다. 이는 예측가능한 개발을 만들어줄 뿐 아니라 유지보수, 협업 등에서도 엄청난 강점을 발휘합니다.

Virtual DOM

from Clipping 3

React의 가장 큰 특징이자 뜨거운 논쟁을 불러일으키는 대상, 그것이 바로 Virtual DOM입니다.

DOM은 웹 개발자들의 영원한 숙제입니다. DOM은 웹의 핵심으로써, 브라우저가 화면을 그리기 위한 정보가 담겨있는 문서입니다. 웹은 원래 인터넷을 통해 공유되는 문서의 규격으로써 탄생했죠. 문제는 이 DOM을 효과적으로 다루는 것이 꽤나 힘들다는 것입니다. 그래서 DOM이 성능이 좋지 않다느니 하는 말도 나오지만 사실 DOM 자체보다는 해석 과정에 문제가 있는 경우가 대부분입니다. 브라우저별로 이 DOM을 가지고 화면을 만드는 방식이 다르기도 하구요.

Jquery는 무엇이 문제였나

Jquery는 누구나 쉽게 DOM을 조작할 수 있도록 하는 아주 멋진 도구였습니다. 그러나 Jquery는 뭔가 구조적 대안이라기 보다는 날카로운 커터칼에 가까운 것이었죠.

앱 전체에 무분별하게 Jquery가 난무하고 있는 코드를 본 적 있으신가요? Javascript로 간단한 계산도 못해도 Jquery는 쓴다느니, 남이 쓴 Jquery를 그냥 갖다 붙이면 된다느니 하는 말이 나오는 것이 바로 Jquery의 장점과 단점을 모두 보여준다고 할 수 있습니다.

Jquery가 인기있었던 이유가 바로 이 커터칼처럼 DOM을 잘라내는 방식에 있었지만, 프론트엔드 개발의 전문성이 높아지고 대형 앱의 유지/보수가 화두가 되면서 이것이 Jquery의 한계로써 드러나게 되었죠.

DOM에 대한 완전히 새로운 접근

from Clipping 3

React의 가장 강력한 개성이 바로 이 Virtual DOM에서 나옵니다. 아래의 코드를 보겠습니다.

class HelloMessage extends React.Component {
  render() {
     return (
        <div>
          <div>Hello {this.props.name}</div>
          <div>I am {this.state.chatName}</div>
       </div>
    );
  }
}

이 HelloMessage 클래스는 만약 this.props.name이 Alex이고, this.state.chatName이 Thom이라면, “Hello Alex”, “I am Jenny” 라는 글자를 유저에게 보여주는 컴포넌트입니다. 그런데 만약 여기서 this.props.name은 그대로이고, this.state.chatName은 “Mary”로 바뀌었다면 어떻게 될까요?

“Hello Alex”, “I am Mary”라는 결과가 브라우저에 나타날 것이라는 건 쉽게 짐작할 수 있죠? 하지만 React는 여기서 한번의 작업 과정을 더 거칩니다. 그리고 이곳이 바로 Virtual DOM이 자신의 역할을 수행하는 부분입니다.

일단 React 컴포넌트는 render를 다시 호출하여 새로운 결과값을 return합니다. 그런데 이 return 값은 바로 DOM에 반영되지 않습니다. 바로 브라우저에 렌더링되지 않는다는 것이죠.

앞에서 React안에 있는 div들은 진짜 html이 아니라 Babel에 의해 컴파일되는 JSX라고 설명했었죠? render함수가 return하는 것은 새로운 Virtual DOM을 만들기 위한 재료입니다. React는 새로운 return 값을 가지고 새로운 Virtual DOM을 만듭니다. 그리고 현재 브라우저에 보여지고 있는 진짜 DOM과 비교하여 어떤 부분이 달라졌는지 찾아냅니다. 그리고 바뀐 부분만 진짜 DOM에 적용합니다. 그러면 브라우저는 이 DOM을 해석하여 유저에게 새로운 화면을 보여주게 되죠.

Vue.js

다음은 Clipping 4, Clipping 5의 글을 재편집한 글입니다.

Vue.js 는 웹 페이지 화면을 개발하기 위한 Front-end Framework이다. 소개의 글에선 Angular.js와 React.js의 장점을 뽑아냈다고 평가하고 있다.

여기서 참고로

  • Framework : 개발자들의 개발 생산성을 높이기 위해 일정한 틀과 규칙에 따라 개발하도록 미리 구조를 정의 해놓은 도구
  • Library : 자주 사용되는 기능들을 모아 재활용 할 수 있도록 정리한 기술 모음집
  • React는 Library고, Vue는 Framework이다.

Vue의 특징은 다음과 같다(공식 동영상).

  • Approachable 진입장벽이 낮고
  • Versatile 유연하고
  • Performant 성능이 좋고
  • Maintainable 유지보수와
  • Testable 테스팅이 편리하고
  • Progressive Framework 점진적인(진보적인) 프레임워크를 지향한다.

Vue의 특징은 다음과 같다(Clipping 5).

vue_structure

출처 : Clipping 5

  • 데이터 바인딩과 화면 단위를 컴포넌트 형태로 제공하며, 관련 API 를 지원하는데에 궁극적인 목적이 있음
  • Angular에서 지원하는 양방향 데이터 바인딩 을 동일하게 제공 하지만 컴포넌트 간 통신의 기본 골격은 React의 단방향 데이터 흐름(부모 -> 자식)을 사용 다른 프런트엔드 프레임워크(Angular, React)와 비교했을 때 상대적으로 가볍고 빠름.
  • 문법이 단순하고 간결하여 초기 학습 비용이 낮고 누구나 쉽게 접근 가능
  • Component로 UI를 구성하고 이는 재사용할 수 있다는 것은 React와 같다. 또한 Virtual DOM을 활용하고 Data에 따라 반응적(Reactvie)이며 유연하고 런타임 퍼포먼스가 괜찮다는 점도 React 와 같다.

즉, Component로 UI를 구성하고 이는 재사용할 수 있다는 것은 React와 같다. 또한 Virtual DOM을 활용하고 Data에 따라 반응적(Reactvie)이며 유연하고 런타임 퍼포먼스가 괜찮다는 점도 React 와 같다. 한글로 된 Vue.js 공식 문서 - Clipping 6

MVVM 패턴이란

mvvm

출처 : Clipping 5

Backend 로직과 Client 의 마크업 & 데이터 표현단을 분리하기 위한 구조로 전통적인 MVC 패턴의 방식에서 기인하였다. 간단하게 생각해서 화면 앞단의 회면 동작 관련 로직과 뒷단의 DB 데이터 처리 및 서버 로직을 분리하고, 뒷단에서 넘어온 데이터를 Model 에 담아 View 로 넘어주는 중간 지점이라고 보면 되겠다.

HTML 기반 템플릿 구문

Vue는 HTML 기반의 전통적인 웹 구조를 반영했다고 한다(Template이라는 문법을 쓰는데 이것이 HTML 기반임). 따라서 진입 장벽이 낮고 배우기 쉽다고 함.

정리하자면

React.js

  • React는 캡슐화된 Component로 UI를 구성한다.
  • 이때 UI는 정적이 아니라 데이터에 따른 동적이다.
  • 복잡한 UI는 Component를 쌓고 이어(결합하여) 구현한다.
  • 이렇게 만든 Component는 다른데서 재사용이 가능하다.
    • Facebook React Core팀의 일원인 Dan Abramov는 React의 목표가 성능보다는 유지가능한 앱을 만드는 것에 있다고 설명한적이 있다고 한다.
  • Virtual DOM 개념을 통해 효율적으로 DOM을 조작한다.
    • Data가 바뀌어 적용될 때 DOM을 직접 뜯어 고치는 것이 아니다.
    • 새로운 Data를 통해 Virtual DOM을 만든다.
    • 브라우저에서 기존에 보여지던 DOM과 Virtual DOM을 비교해 바뀐 부분만 DOM에 적용한다(효율적).
  • 즉 변하는 Data(실시간 Data라던지)에 대해 유연하게 대처할 수 있으며, 유지/보수하기 쉽다.
  • 생태계, 확장 라이브러리 등 커뮤니티가 크고 활발하다.

Vue.js

  • Vue도 React와 많이 닮아 있다.
  • 공식문서에 따르면 React의 영향을 많이 받았다고 함(React 출시 2013년, Vue 출시 2014년).
  • 캡슐화된 Component로 UI를 구성하고
  • Component는 재사용이 가능하며
  • Virtual DOM을 활용하여 유연하고 유지/보수가 쉽다.
  • 단 커뮤니티가 그렇게 활발하지 않다고 한다(활발 보다는 크지 않다가 적절한 표현).

그래서 React? Vue?

React는 왔고, Vue는 오고 있다.

블로그를 점진적으로 꾸준히 개선(기능 추가)해 나갈 거라면 Vue

관리(유지/보수)의 수월함과 개발 커뮤니티, 블로그의 크기를 키울 것이라고 생각하면 React

근데 사실 Hello World 해보고 취향따라 해도 될 것 같다.

Reference

React.js

Vue.js

예제 Example

from Cipping 1

간단한 컴포넌트

React 컴포넌트는 render()라는 메서드를 구현하는데, 이것은 데이터를 입력받아 화면에 표시할 내용을 반환하는 역할을 합니다. 이 예제에서는 XML과 유사한 문법인 JSX를 사용합니다. 컴포넌트로 전달된 데이터는 render() 안에서 this.props를 통해 접근할 수 있습니다.

React를 사용하기 위해서 JSX가 꼭 필요한 것은 아닙니다. JSX를 컴파일한 JavaScript 코드를 확인하려면 Babel REPL을 이용해보세요.

class HelloMessage extends React.Component {
  render() {
    return (
      <div>
        Hello {this.props.name}
      </div>
    );
  }
}

ReactDOM.render(
  <HelloMessage name="Taylor" />,
  document.getElementById('hello-example')
);

상태를 가지는 컴포넌트

컴포넌트는 this.props를 이용해 입력 데이터를 다루는 것 외에도 내부적인 상태 데이터를 가질 수 있습니다. 이는 this.state로 접근할 수 있습니다. 컴포넌트의 상태 데이터가 바뀌면 render()가 다시 호출되어 마크업이 갱신됩니다.

class Timer extends React.Component {
  constructor(props) {
    super(props);
    this.state = { seconds: 0 };
  }

  tick() {
    this.setState(state => ({
      seconds: state.seconds + 1
    }));
  }

  componentDidMount() {
    this.interval = setInterval(() => this.tick(), 1000);
  }

  componentWillUnmount() {
    clearInterval(this.interval);
  }

  render() {
    return (
      <div>
        Seconds: {this.state.seconds}
      </div>
    );
  }
}

ReactDOM.render(
  <Timer />,
  document.getElementById('timer-example')
);

애플리케이션

propsstate를 사용해서 간단한 Todo 애플리케이션을 만들 수 있습니다. 이 예제에서는 state를 사용해 사용자가 입력한 텍스트와 할 일 목록을 관리합니다. 이벤트 핸들러들이 인라인으로 각각 존재하는 것처럼 보이지만, 실제로는 이벤트 위임을 통해 하나로 구현됩니다.

class TodoApp extends React.Component {
  constructor(props) {
    super(props);
    this.state = { items: [], text: '' };
    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  render() {
    return (
      <div>
        <h3>TODO</h3>
        <TodoList items={this.state.items} />
        <form onSubmit={this.handleSubmit}>
          <label htmlFor="new-todo">
            What needs to be done?
          </label>
          <input
            id="new-todo"
            onChange={this.handleChange}
            value={this.state.text}
          />
          <button>
            Add #{this.state.items.length + 1}
          </button>
        </form>
      </div>
    );
  }

  handleChange(e) {
    this.setState({ text: e.target.value });
  }

  handleSubmit(e) {
    e.preventDefault();
    if (this.state.text.length === 0) {
      return;
    }
    const newItem = {
      text: this.state.text,
      id: Date.now()
    };
    this.setState(state => ({
      items: state.items.concat(newItem),
      text: ''
    }));
  }
}

class TodoList extends React.Component {
  render() {
    return (
      <ul>
        {this.props.items.map(item => (
          <li key={item.id}>{item.text}</li>
        ))}
      </ul>
    );
  }
}

ReactDOM.render(
  <TodoApp />,
  document.getElementById('todos-example')
);

외부 플러그인을 사용하는 컴포넌트

React는 유연하며 다른 라이브러리나 프레임워크를 함께 활용할 수 있습니다. 이 예제에서는 외부 마크다운 라이브러리인 remarkable을 사용해 <textarea>의 값을 실시간으로 변환합니다.

class MarkdownEditor extends React.Component {
  constructor(props) {
    super(props);
    this.md = new Remarkable();
    this.handleChange = this.handleChange.bind(this);
    this.state = { value: 'Hello, **world**!' };
  }

  handleChange(e) {
    this.setState({ value: e.target.value });
  }

  getRawMarkup() {
    return { __html: this.md.render(this.state.value) };
  }

  render() {
    return (
      <div className="MarkdownEditor">
        <h3>Input</h3>
        <label htmlFor="markdown-content">
          Enter some markdown
        </label>
        <textarea
          id="markdown-content"
          onChange={this.handleChange}
          defaultValue={this.state.value}
        />
        <h3>Output</h3>
        <div
          className="content"
          dangerouslySetInnerHTML={this.getRawMarkup()}
        />
      </div>
    );
  }
}

ReactDOM.render(
  <MarkdownEditor />,
  document.getElementById('markdown-example')
);

Clone this wiki locally