리액트 (자바스크립트 라이브러리)

리액트(React, React.js 또는 ReactJS)는 자바스크립트 라이브러리의 하나로서 사용자 인터페이스를 만들기 위해 사용된다. 페이스북과 개별 개발자 및 기업들 공동체에 의해 유지보수된다.

리액트는 싱글 페이지 애플리케이션이나 모바일 애플리케이션 개발에 사용될 수 있다.  대규모 또는 복잡한 리액트 애플리케이션 개발에는 보통 라우팅, API통신 등의 기능이 요구되는데  리액트에는 기본적으로 제공되지 않기 때문에 추가 라이브러리를 사용해야 한다.

역사 
리액트는 페이스북의 소프트웨어 엔지니어 Jordan Walke가 개발하였다. 그는 PHP용 HTML 컴포넌트 프레임워크인 XHP에 영향을 받았다.
2011년 페이스북의 뉴스피드에 처음 적용되었다가 2012년 인스타그램닷컴에 적용되었다. 2013년 5월 JSConf US에서 오픈 소스화되었다.

기본 사용법 
다음은 JSX와 자바스크립트와 함께 HTML에 사용한 기초적인 예제이다.
<div id="myReactApp"></div>

<script type="text/babel">
  class Greeter extends React.Component {
    render() {
      return <h1>{this.props.greeting}</h1>
    }
  }

  ReactDOM.render(<Greeter greeting="Hello World!" />, document.getElementById('myReactApp'));
</script>
Greeter 클래스는 greeting 속성을 수용하는 리액트 컴포넌트이다.
ReactDOM.render 메서드는 Greeter 컴포넌트의 인스턴스를 생성하고 greeting 속성을 'Hello World'로 설정하며 렌더링된 컴포넌트를 차일드 요소로서 myReactApp id의 DOM 요소로 추가한다.

웹 브라우저에 표시될 때 결과는 다음과 같다.
<div id="myReactApp">
  <h1>Hello World!</h1>
</div>

주요 특징

속성과의 단방향 데이터 바인딩 
보통 props라 불리는 속성들은 부모 컴포넌트로부터 컴포넌트에 전달된다. 컴포넌트들은 props을 하나의 불변의 값(자바스크립트 객체)들로 받는다.

스테이트풀 컴포넌트 
상태를 컴포넌트를 통해 값을 보관하며 props를 통해 차일드 컴포넌트로 전달할 수 있다:
class ParentComponent extends React.Component {
  state = { color: 'red' };
  render() {
    return (
      <ChildComponent color={this.state.color} />
    );
  }
}

가상 DOM 
다른 저명한 기능은 가상 문서 객체 모델, 즉 가상 DOM의 사용이다. 리액트는 인 메모리 데이터 구조 캐시를 만들고 결과 차이를 계산한 다음 브라우저에 표시되는 DOM을 효과적으로 업데이트한다. 이로써 프로그래머는 마치 모든 페이지가 변경될 때마다 렌더링되는 것처럼 코드를 작성할 수 있는데, 실제로 리액트 라이브러리는 단지 실제로 변경되는 하위 컴포넌트만을 렌더링할 뿐이다.

라이프사이클 메서드 
라이프사이클 메서드들은 컴포넌트가 생존하는 동안 셋 포인트(set point)에 코드를 실행할 수 있게 하는 훅(hook)이다.

 shouldComponentUpdate는 렌더가 불필요한 경우 false를 반환함으로써 개발자가 컴포넌트의 불필요한 재렌더링을 막을 수 있게 한다.
 componentDidMount는 컴포넌트가 '마운트'(mount)되면 호출된다. (대개 컴포넌트 DOM 노드와 연결함으로써 사용자 인터페이스에서 만들어진다) API를 통해 원격 소스로부터 로드되는 데이터를 트리거(trigger)하기 위해 보통 사용된다.
 render는 가장 중요한 라이프사이클 메서드이며 어떠한 컴포넌트에서도 최소한의 필요 조건이다. 컴포넌트의 상태가 업데이트될 때마다 호출되는 것이 보통이며 사용자 인터페이스의 변경사항을 반영한다.

JSX 
JSX(JavaScript XML)는 XML같은 문법을 사용하는 ECMAScript의 확장이다. HTML과 모습이 비슷해 보이는 JSX는 수많은 개발자들에게 친숙한 문법을 사용하여 컴포넌트 렌더링을 구조화하는 방법을 제공한다. 리액트 컴포넌트들은 일반적으로 JSX를 사용하여 작성되지만 꼭 그렇게 할 필요는 없다. (컴포넌트들은 순수 자바스크립트로 작성할 수도 있다) JSX는 PHP를 위해 페이스북이 개발한 다른 확장 문법인 XHP와 유사하다.

JSX 코드의 예는 다음과 같다:
class App extends React.Component {
  render() {
    return (
      <div>
        <p>Header</p>
        <p>Content</p>
        <p>Footer</p>
      </div>
    );
  }
}
 내재된(nested) 요소
같은 레벨의 여러 요소들은 위와 같이 <div> 요소와 같이 하나의 컨테이너 요소로 감싸거나
배열로 반환해야 한다.

속성(Attributes)
JSX는 HTML이 제공하는 것을 미러링하도록 설계된 일련의 요소 속성들을 제공한다. 사용자 지정 속성들은 컴포넌트로 전달할 수도 있다. 모든 속성은 컴포넌트를 props로 받는다.

자바스크립트 식(JavaScript expressions)
자바스크립트 식(문은 아님)은 중괄호 {}를 사용하여 JSX 안에 쓸 수 있다:
  <h1>{10+1}</h1>

위의 예는 다음과 같이 렌더링한다.
  <h1>11</h1>

조건문
If–else 문은 JSX 안에서 사용할 수 없으나 조건문을 대신 사용할 수 있다. 아래의 예는 { i === 1 ? 'true' : 'false' }를 문자열 'true'로 렌더링하는데, 그 이유는 i는 1과 동등하기 때문이다.
class App extends React.Component {
  render() {
    const i = 1;
    return (
      <div>
        <h1>{ i === 1 ? 'true' : 'false' }</h1>
      </div>
    );
  }
}
함수와 JSX는 조건들 안에 사용이 가능하다:
class App extends React.Component {
  render() {
    const sections = [1, 2, 3];
    return (
      <div>
        {
          sections.length > 0
            ? sections.map(n => <div>Section {n}</div>)
            : null
        }
      </div>
    );
  }
}
위는 다음과 같이 렌더링된다:
<div>
  <div>Section 1</div>
  <div>Section 2</div>
  <div>Section 3</div>
</div>

JSX로 작성된 코드는 웹 브라우저가 인식할 수 있기 전에 바벨과 같은 도구를 이용한 변환이 필요하다. 이러한 처리는 일반적으로 애플리케이션이 디플로이되기 전에 소프트웨어 빌드 과정 중에 수행된다.

단순 HTML 랜더링 그 이상의 아키텍처 
리액트의 기본 구조는 웹 브라우저에서 렌더링되는 HTML을 넘어서 적용된다. 이를테면 페이스북은 <canvas> 태그에 렌더링하는 동적인 차트를 가지고 있으며, 넷플릭스와 페이팔은 서버와 클라이언트 쪽에 유사 HTML을 렌더링하기 위한 동일 구조의 적재(isomorphic loading)를 사용한다.

리액트 네이티브 

리액트 네이티브는 2015년에 페이스북에 의해 발표되었으며 네이티브 안드로이드, iOS, UWP 애플리케이션에 리액트 아키텍처를 적용한다.

Hello World
import React, { Component } from 'react';
import { AppRegistry, Text } from 'react-native';

export default class HelloWorldApp extends Component {
  render() {
    return (
      <Text>Hello world!</Text>
    );
  }
}

// Skip this line if using Create React Native App
AppRegistry.registerComponent('HelloWorld', () => HelloWorldApp);

// The ReactJS code can also be imported into another component with the following code:

import HelloWorldApp from './HelloWorldApp';

비평 
리액트는 "가상 DOM"의 개념을 이용하기 때문에 다량의 메모리(RAM)가 필요하다는 비평이 있다. 이는 UI의 표현이 메모리에 상주되어 ReactDOM과 같은 라이브러리에 의해 실제 DOM과 동기화되는 방식이다.

같이 보기 
 빌드 자동화
 리덕스

각주

외부 링크 
 

자바스크립트 라이브러리
2015년 소프트웨어
Ajax
웹 애플리케이션
페이스북 소프트웨어
MIT 라이선스 소프트웨어