6 minute read

리액트 개요

요약하면 리액트(React)는 사용자 인터페이스를 만들기 위한 JavaScript 라이브러리 이다. (매우 인기있는!) 웹 애플리케이션의 사용자 인터페이스(UI)를 구축하기 위해 사용된다.

  • 컴포넌트 기반으로 동작하며, 컴포넌트를 조합하여 사용자 인터페이스(UI)를 구축.
  • JSX 문법으로 정의한 컴포넌트 사용.

왜 리액트인가? 등장배경

  1. 자바스크립트의 열광
    1. 1995년, 브렌던 아이크(Brendan Eich)가 넷스케이프(Netscape) 브라우저를 위해 개발한 Mocha 언어를 기반으로 LiveScript 언어를 만듭니다.
    2. 1996년, 넷스케이프에서 LiveScript를 JavaScript로 변경하면서 자바와의 연관성을 강조하고, 모카와의 연관성을 줄입니다.
    3. 1997년, ECMAScript 1 버전이 발표됩니다. 이후 버전은 ECMAScript 2, 3, 4 순서로 발표됩니다.
    4. 2004년, AJAX(Asynchronous JavaScript and XML)가 등장하면서 자바스크립트가 웹 개발에서 중요한 역할을 하게 됩니다.
    5. 2005년, Jesse James Garrett이 “Ajax: A New Approach to Web Applications”을 발표하면서 자바스크립트의 역할이 강조됩니다.
    6. 2006년, jQuery가 등장하면서 자바스크립트로 DOM(Document Object Model)을 조작하는 것이 훨씬 쉬워집니다.
    7. 2008년, Google이 V8 자바스크립트 엔진을 개발하면서 자바스크립트의 속도가 크게 향상됩니다.
    8. 2009년, CommonJS 프로젝트에서 모듈 시스템의 표준화를 제안합니다.
    9. 2010년, Node.js가 등장하면서 서버 측 자바스크립트 프로그래밍이 가능해집니다.
    10. 2011년, CoffeeScript가 등장하면서 자바스크립트의 문법이 더욱 간결해집니다.
    11. 2015년, ECMAScript 6 버전이 발표되면서 클래스, 모듈 등의 기능이 추가됩니다.
    12. 2016년, React Native가 등장하면서 자바스크립트로 모바일 애플리케이션을 개발하는 것이 가능해집니다.
    13. 2017년, Vue.js가 등장하면서 자바스크립트 기반의 프론트엔드 프레임워크 중 하나로 자리 잡습니다.
    14. 2018년, TypeScript가 등장하면서 자바스크립트의 타입 시스템을 보완합니다.
    15. 현재는 React, Angular, Vue.js 등을 비롯한 다양한 프론트엔드 프레임워크가 자바스크립트를 기반으로 발전하고 있습니다.
  2. getElementById() 의 효율성 의심
    • 특정 id 값을 업데이트하려면 요소를 찾고 수정하는게 당연했다. 이는 규칙이 간단하지만 애플리케이션이 거대해지면 성능이 떨어질 수 있다.
  3. 페이스북의 [기존뷰를 날리자] 아이디어
    • 특정 요소에 데이터가 변할때마다 어떤 변화를 줄지 고민하는 것이 아닌 그냥 기존뷰를 날리고 처음부터 새로 랜더링하자 개념이 나옴
    • 어떻게 변화를 줄지 생각할 필요없이 그저 그 뷰가 어떻게 생길지 선언하며 데이터변화만 감지하여 기존 것은 버리고 정해진규칙에 따라 새롭게 랜더링함.

      근데 이방식이 가능할까?)
      웹브라우저에서 이방식은 CPU는 오르고 DOM은 느리고 메모리도 많이 먹는다. 그리고 사용자가 인풋박스에 입력마다 기존 랜더링은 사라지고 새로랜더링하면 끊킬것이다. 근데 페이스북이 이걸 최대한 성능을 아끼고 편안한 사용자경험을 제공하면서 구현한 것이 바로 리액트이다.

리액트의 이해

리액트는 MVC, MVW 등의 프레임웍과 다르게 오직 V만 신경쓰는 라이브러리이다.
기본적인 용어는 다음과 같다.

  • 컴포넌트
    특정 부분이 어떻게 생길지 정하는 선언체
  • 랜더링
    사용자 화면에 뷰를 보여주는 것 (초기 렌더링 / 조화 과정)

어떻게하면 페이스북이 구현한 데이터가 변해도 성능을 아끼는 개념을 이해할 수 있을까? 이는 리렌더링 개념을 이해해야 한다.

렌더링(초기 렌더링)

어떤 UI 프레임웍이던 맨 처음 어떻게 보일지 초기렌더링이 필요하다.

// (렌더링 -> HTML 마크업 -> DOM)
render() {...}
  • 컴포넌트가 어떻게 생겼는지 정의한다.
  • html 형식의 문자열을 반환하지 않고 뷰가 어떻게 생겼고 어떻게 작동하는지에 대한 정보를 지닌 객체를 반환한다.
  • 컴포넌트 내부에는 또 다른 컴포넌트가 들어갈 수 있다. 이때 render()를 실행하면 그 내부에 있는 컴포넌트들도 재귀적으로 렌더링한다.
  • 최상위 컴포넌트의 렌더링 작업이 끝나면 반환된 정보들을 사용하여 HTML 마크업을 만들고, 실제 페이지의 DOM 요소 안에 주입한다. (초기 렌더링)

렌더링(조화 과정)

업데이트를 거친다 라기보단 조화 과정을 거친다가 정확한 표현이다.

  • 컴포넌트는 데이터를 업데이트했을 때 단순히 업데이트한 값을 수정하는 것이 아니라, 새로운 데이터를 가지고 render 함수를 또 호출한다. 즉 새롭게 갈아끼우게 된다.

Virtual DOM

  • DOM (Document Object Model)
    • HTML, XML 문서의 각 요소들을 계층적으로 표현하여 문서 내 요소들을 생성, 변경, 삭제할 수 있도록 돕는 인터페이스
  • DOM은 과연 느릴까?
    • DOM 자체는 빠르다. DOM 자체를 읽고 쓸 때의 성능은 빠르다.
    • 하지만 웹 브라우저 단에서 DOM에 변화(업데이트)가 일어나면 웹 브라우저가 CSS를 다시 연산하고, 레이아웃을 구성하고, 페이지를 리페인트한다. (시간 소모가 크다)
    • DOM을 조작할 때마다 엔진이 웹페이지를 새로 그리기 때문에 업데이트가 너무 잦으면 성능이 저하될 수 있다.
  • 해결법 : DOM을 최소한으로 조작한다!
    • Virtual DOM을 이용하여 DOM 업데이트를 추상화함으로써 DOM 처리 횟수를 최소화하고 효율적으로 진행한다.
    • Virtual DOM을 사용하면 실제 DOM에 접근하여 조작하는 대신, 이를 추상화한 자바스크립트 객체를 구성하여 사용한다. (실제 DOM보다 가벼운 사본)
    • 리액트에서 뷰를 업데이트할 때 “업데이트 과정을 거친다”라고 하기보다는 “조화(reconciliation)과정을 거친다”라고 하는 것이 정확한 표현이다.
      • 컴포넌트는 데이터를 업데이트 했을 때, 새로운 데이터를 가지고 render()를 호출한다.
      • 하지만 이때 반환된 결과가 곧바로 실제 DOM에 반영하지 않는다.
      • 데이터가 업데이트되면, 전체 UI를 Virtual DOM에 리렌더링 한다.
      • 이전 Virtual DOM에 있던 내용과 현재 내용을 비교한다.
      • 바뀐 부분만 실제 DOM에 적용한다.

        1. 데이터를 업데이트하면 전체 UI를 Virtual DOM에 리렌더링한다.(실제DOM X)
        2. 이전 Virtual DOM에 있던 내용과 현재 내용을 비교한다.
        3. 바뀐 부분만 실제 DOM에 적용한다.

💡 지속적으로 데이터가 변화하는 대규모 애플리케이션 효율적으로 구축하기 위해 React 탄생
💡 React와 Virtual DOM이 제공할 수 있는 것은 View 업데이트 처리 간결성이다.

리액트의 이해 (상세)

강점

  • 선언적 UI
    리액트는 선언적인 방식으로 UI를 구성할 수 있어, UI의 상태 변화에 따른 업데이트를 효율적으로 처리할 수 있다. 이는 코드의 가독성과 유지보수성을 높인다.
      function App() {
        return (
          <div>
            <h1>Hello, World!</h1>
            <p>This is a simple example of a declarative UI in React.</p>
          </div>
        );
      }
        
    
    • 위 코드는 단순한 HTML처럼 보이지만, 실제로는 JSX라는 문법으로 XML과 비슷한 형태의 문법을 사용하여 UI를 표현할 수 있다.
    • 이를 리액트가 이해하여 렌더링하면, 실제 DOM 요소가 생성되어 화면에 출력한다.
    • 이렇게 선언적으로 UI를 구현하면, 코드의 가독성과 유지보수성이 좋아지며, 리액트가 자동으로 상태 변화를 감지하여 UI를 업데이트하기 때문에 개발자가 일일이 DOM 요소를 조작하거나 관리할 필요가 없다.
  • 가상 DOM(Virtual DOM)
    리액트는 가상 DOM을 사용하여 실제 DOM 조작을 최소화하고, 변경된 부분만 업데이트함으로써 UI 업데이트의 성능을 향상시킨다. 이는 웹 애플리케이션의 빠른 렌더링을 가능하게 한다.
      // 클래스형 컴포넌트로 작성한 경우
      import React from 'react';
      class Example extends React.Component {
        constructor(props) {
          super(props);
          this.state = { count: 0 };
        }
        handleClick() {
          this.setState(prevState => ({ count: prevState.count + 1 }));
        }
        render() {
          return (
            <div>
              <p>You clicked {this.state.count} times</p>
              <button onClick={() => this.handleClick()}>
                Click me
              </button>
            </div>
          );
        }
      }
      /* 이 코드에서 handleClick 함수를 실행하면 this.state.count 값이 변경 된다. */
    
      // 함수형 컴포넌트로 작성한 경우
      import React, { useState } from 'react';
      function Counter() {
        const [count, setCount] = useState(0);
        function handleIncrement() {
          setCount(count + 1);
        }
        function handleDecrement() {
          setCount(count - 1);
        }
        return (
          <div>
            <h1>Count: {count}</h1>
            <button onClick={handleIncrement}>Increment</button>
            <button onClick={handleDecrement}>Decrement</button>
          </div>
        );
      }
      export default Counter;
      /* 이 코드에서 handleClick 함수를 실행하면 this.state.count 값이 변경 된다. */
    
    • 변경된 count 값에 대한 렌더링 결과를 적용하기 위해, 리액트는 가상 DOM을 사용하여 변경된 부분만 실제 DOM에 업데이트 한다.
    • 즉, 전체 DOM을 새로 그리지 않아도 필요한 부분만 업데이트할 수 있게 된다. 이는 렌더링 성능을 향상시키는데 큰 역할을 한다.

      요약)
      리액트에서 변경된 부분을 감지하는 과정에서 DOM이 아니라 Virtual DOM을 한다. 변경 사항을 확인하고 적용하기 위해 React는 변경 사항이 발생한 부분만 실제 DOM과 비교하고 업데이트 한다.

  • 컴포넌트 기반 개발
    리액트는 컴포넌트 기반의 개발을 지원하여, UI를 재사용 가능한 컴포넌트로 구성할 수 있다. 이는 코드의 재사용성을 높이고 개발 생산성을 향상시킨다. 컴포넌트 기반의 개발 방식의 종류는 크게 함수형 컴포넌트클래스형 컴포넌트로 나눈다. 최근에는 함수형 컴포넌트를 주로 사용하는 추세이며, 리액트 훅(Hook) 기능의 추가로 함수형 컴포넌트에서도 상태(state)를 다룰 수 있게 되어 더욱 강력해졌다. 또한, 클래스형 컴포넌트에서만 사용할 수 있는 라이프사이클 메서드도 있다.

    클래스형 컴포넌트 개발 방식

      // MyButton.js
      import React, { Component } from 'react';
      class MyButton extends Component {
        render() {
          return (
            <button onClick={this.props.onClick}>Click me!</button>
          );
        }
      }
      export default MyButton;
    
      // App.js
      import React, { Component } from 'react';
      import MyButton from './MyButton';
      class App extends Component {
        handleClick() {
          console.log('Button clicked!');
        }
        render() {
          return (
            <div>
              <h1>Hello World!</h1>
              <MyButton onClick={this.handleClick} />
            </div>
          );
        }
      }
      export default App;
    

    함수형 컴포넌트 개발 방식

      // MyButton.js
      import React from 'react';
      function MyButton(props) {
        return (
          <button onClick={props.onClick}>Click me!</button>
        );
      }
      export default MyButton;
    
      // App.js
      import React from 'react';
      import MyButton from './MyButton';
      function App() {
        function handleClick() {
          console.log('Button clicked!');
        }
        return (
          <div>
            <h1>Hello World!</h1>
            <MyButton onClick={handleClick} />
          </div>
        );
      }
      export default App;
    
  • 큰 생태계
    리액트는 많은 개발자 커뮤니티와 다양한 생태계를 가지고 있어, 다양한 도구와 라이브러리를 활용할 수 있다. 또한, 리액트는 Facebook 및 Instagram 등의 대규모 애플리케이션에서 검증된 기술이기도 하다.

약점

  • 복잡성
    리액트는 처음 사용하는 개발자에게는 학습 곡선이 있을 수 있다. 특히, JSX 문법과 컴포넌트 기반의 개발 방식에 익숙하지 않은 경우에는 익숙해지는 데 시간이 걸릴 수 있다.
  • 단순한 View 라이브러리
    리액트는 UI를 관리하는 라이브러리로, 상태 관리, 라우팅, 데이터 통신과 같은 기능은 제공하지 않는다. 따라서, 별도의 상태 관리 라이브러리나 추가적인 라이브러리를 도입해야 할 수도 있다.
  • 생태계의 빠른 변화
    리액트의 생태계는 빠르게 변화하고 있어, 새로운 버전이 나올 때마다 기존 코드의 업데이트와 호환성이 급격하게 변화한다.

Tags:

Categories:

Updated:

Leave a comment