React(라이브러리)

덤프버전 : r20240101





리액트
React
파일:React 로고.svg
종류
라이브러리
라이선스
MIT 라이선스
개발
파일:메타(기업) 로고.svg[[파일:메타(기업) 로고 컬러 화이트.svg
언어
JavaScript
버전
18.2.0 (2022. 6. 14. 업데이트)
링크
파일:홈페이지 아이콘.svg 파일:GitHub 아이콘.svg[[파일:GitHub 아이콘 화이트.svg
파일:페이스북 아이콘.svg
파일:X Corp 아이콘(블랙).svg


1. 개요
2. 예시
2.1. 해설
2.2. 리액트가 있고 없고의 차이 (컴포넌트)
3. Virtual DOM
4. JSX
5. 개발환경 만들기
5.1. npx
5.2. yarn
6. React Native
6.1. 개요
6.2. 지원 플랫폼
6.3. 다른 라이브러리와의 비교
6.4. 크로스 플랫폼(?)
7. React를 사용하는 웹 사이트/프로그램
8. 여담



1. 개요[편집]


메타에서 개발한 오픈 소스 자바스크립트 라이브러리.

프론트엔드 개발자 사이에서 AngularJS, Vue.js와 더불어 많은 인기를 얻고 있다. GitHub Star 수와 npm 패키지 다운로드 수는 React가 가장 많다.

SPA#Single Page Application을 전제로 하고 있으며, Dirty checking과 Virtual DOM을 활용하여 업데이트 해야하는 DOM 요소를 찾아서 해당 부분만 업데이트하기 때문에, 리렌더링이 잦은 동적인 모던 웹에서 엄청나게 빠른 퍼포먼스를 내는게 가능하다. 기본적으로 모듈형 개발이기 때문에 생산성 또한 상당히 높은 라이브러리인지라 순식간에 대세로 떠올랐다. 거기에 기본적으로 프레임워크가 아니라 라이브러리인지라 다른 프레임워크에 간편하게 붙여서 사용하는 것도 가능하며, React Hooks라는 강력한 메소드들을 지원하면서 사실상 웹 프론트엔드 개발의 표준으로 자리잡았다. 이와 더불어 타입스크립트Sass 같은 언어도 지원한다. 또한 Next.js 등의 등장으로 인해 SSG, SSR등을 할 수 있게 되면서 사용 범위 또한 기하급수적으로 늘어났다.


2. 예시[편집]


함수 문법 (권장)
import ReactDOM from 'react-dom';

function App ({name}){
  return (
    <h1>Hello, {name}!</h1>
  )
}

ReactDOM.render(<App name="홍길동" />, document.getElementById('root'));

클래스 문법 (비권장)
[ 펼치기 / 접기 ]
import React from 'react';
import ReactDOM from 'react-dom';

class App extends React.Component {
  render() {
    return (
      <h1>Hello, {this.props.name}!</h1>
    )
  }
}

ReactDOM.render(<App name="홍길동" />, document.getElementById('root'));

해당 코드는 최신 브라우저에서 막 지원하기 시작한 import문과, JS 표준 문법이 아닌 JSX를 사용했기 때문에 이 코드가 그대로 브라우저상에 작동되는 것은 아니다. Babel을 통해 대부분의 브라우저가 사용할 수 있는 JS 코드로 변환한 후 사용할 수 있다.


2.1. 해설[편집]


function App ({ name }) {
  return (
    <h1>Hello, {name}!</h1>
  );
}
({ name }) 은, JavaScript 또는 TypeScript에서 사용할 수 있는 destructuring(구조 분해 할당)이라는 문법을 사용한 부분이다. 즉, App이라는 함수의 첫번째 인자의 name이라는 속성을 name이라는 변수에 할당한 것이다.

또한 Return 뒤에 HTML태그처럼 보이는것이 나오는데, 이는 JSX로 Virtual DOM(React Element)을 생성하는 부분이다. 풀어쓰면 다음과 같다. JSX 가 일반적인 함수 호출로 변경되었다.

import { jsx } from "react/jsx-runtime";

function App(props) {
  const name = props.name;
  return jsx("h1", {
    children: ["Hello, ", name, "!"]
  });
}



2.2. 리액트가 있고 없고의 차이 (컴포넌트)[편집]


  • 리액트가 없을 때
<header>
  <h1>Logo</h1>
</header>
<nav>
 <ul>
  <li>
    <a href="#">메뉴1</a>
  </li>
  <li>
    <a href="#">메뉴2</a>
  </li>
 </ul>
</nav>
<section>
  <p>Hello World!</p>
</section>


  • 리액트가 있을 때
const Hlogo = () => {
  return (
    <header>
      <h1>Logo</h1>
    </header>
  );
};

const Anav = () => {
  return (
    <nav>
      <ul>
        <li>
          <a href="#">메뉴1</a>
        </li>
        <li>
          <a href="#">메뉴2</a>
        </li>
      </ul>
    </nav>
  );
};

const Bsection = ({ amumal }) => {
  return (
    <section>
      <p>{amumal}</p>
    </section>
  );
};

const App = () => {
  return (
    <div className="App">
      <Hlogo />
      <Anav />
      <Bsection amumal="Hello World!" />
    </div>
  );
};

export default App;


(위에서 보는 것처럼 컴포넌트 클래스 값은 대문자로 시작되어야 한다.)

위와 같이 컴포넌트(부품)로 나누어서 정리가 가능하다. 이렇게 코드가 짧을 때에는 별로 의미가 없지만 한 페이지의 코드가 길 때에는 코드를 나누어 담을 수 있어서 유용하다. 또한 각 컴포넌트들은 js 파일로 만들어서 공유가 가능하기 때문에 이미 만들어진 컴포넌트들을 조립하여 웹페이지를 만들 수 있어서 가능성이 무궁무진해진다.

참고로 메타에서는 크롬 개발자 도구를 이용해서 리액트로 만들고 있는 페이지의 리액트 컴포넌트들을 볼 수 있는 툴을 제공하고 있다.


3. Virtual DOM[편집]




Virtual DOM의 작동방식을 비유적으로 설명한 영상(영어)

서버와의 데이터 통신과는 별개로 DOM을 직접적으로 조작해야하는 기존의 웹 화면 개발 방식과 달리, React는 DOM을 직접적으로 조작하지 않고 데이터가 변화할 때 변경사항이 적용된 Virtual DOM을 만든다. 그 다음 실제 DOM과 Virtual DOM의 차이점을 비교하고, 변경된 부분을 실제 DOM에 적용한다.

보여지는 데이터의 잦은 변경이 필요한 웹앱의 경우 이러한 방식을 통해 성능을 크게 향상시킬 수 있다. 실제 동적인 웹일수록 Angular 등과 비교해서 성능이 훨씬 더 빠른 편이다. 단, 데이터가 자주 변경되지 않는 비교적 정적인 웹 페이지에 이를 적용할 경우 오히려 성능면에서 손해를 볼 수 있다.


4. JSX[편집]


const element = <h1>Hello, world!</h1>;

JavaScript XML

React에서 HTML을 표현할 때, JSX를 사용한다. 외관상 HTML같은 마크업 언어를 리터럴로 입력하는 것으로 보이는데, 빌드 시 Babel에 의해 자바스크립트로 변환된다. 자바스크립트 코드를 HTML처럼 표현할 수 있기 때문에 용이한 개발이 가능하다.

HTML과 매우 흡사하긴 하지만, XML을 기반으로 한데다 Javascript 내부에서 사용하다보니 불가피하게 생긴 차이점이 몇가지 있다.
  • HTML요소에 class값을 정의할 때, 원래 HTML에서는

    과 같이 하면 되었지만, class라는 단어가 ECMAScript6의 클래스 문법과 겹치는 예약어이기 때문에 대신에 className이라는 단어를 사용한다.
  • 마찬가지 이유로 루프문 예약어와 겹치는 for은 htmlFor로 사용한다.
  • 또한 요소에서 이벤트를 핸들링하는 onclick 등의 단어들은 onClick처럼 카멜표기법으로 표기해야 한다.
  • 기존의 HTML에서 주석은
    이렇게 했었지만 JSX에서는
    {/*주석*/}
    으로 표현한다.
  • HTML Custom-Element는
    와 같이 표기했지만 React의 Custom Element는
    와 같이 Pascal Case로 표기한다. 닫는 태그에는 꼭 명시적으로 /> 표기를 해준다. [1]
  • JSX 내부에서도 JS를 사용할 수 있다. {}로 불러온다.
    {console.log(this.props)}
    같은 식이다.[2]

이 JSX 위주의 프론트엔드 라이브러리로는 Preact, SolidJS, Inferno 등이 있으며, Vue.js 등의 자체적인 포멧을 사용하거나 Svelte 같이 JSX 사용과 거리가 먼 라이브러리 및 프레임워크 또한 JSX를 사용할 수 있는 방법이 존재한다.

어도비Photoshop, After Effects등의 프로그램에서 쓰이는 스크립트의 확장자명도 jsx이지만 이 jsx와는 자바스크립트라는 것 이외의 관련이 없다.


5. 개발환경 만들기[편집]


개발환경 구축은 npx나 yarn 중에서 선택하면 된다.


5.1. npx[편집]


  • 설치
Node.js를 설치해서 npm이 함께 설치되게 한 다음에 프로젝트를 만들 폴더의 터미널에서
npx create-react-app .
을 입력한다.(점까지 모두 입력되어야 한다.)


만일 다른 이름으로 프로젝트를 만들고자 한다면
npx create-react-app [Project name]
을 입력한다.


참고로 npx를 이용한 설치는 npm -g 처럼 노드 환경을 사용하는 pc 자체에 깔리는 것이 아니고 node module이 설치된 프로젝트 내부에만 설치되는 것도 아니다. create-react-app은 처음 프로젝트를 생성할 때만 필요하고 그 이후에는 있을 필요가 없기 때문에 npx를 사용해 1회성으로 설치 후 자동 삭제된다. npm 5버전 이상부터는 npx가 자동으로 지원된다. 그렇지 못한 경우에는 다음과 같이 npx를 설치할 수 있다.
npm install npx -g


참고로 자바스크립트가 아닌 타입스크립트를 사용하려면
npx create-react-app . --template typescript
를 입력하면 된다.


  • 실행
npm start
를 터미널에서 입력하면 리액트가 실행된다. 실행을 종료하고 싶다면 Ctrl+C를 터미널에서 누르면 된다.

실행되면 리액트 폴더의 src/app.js 파일을 통해 페이지 수정을 하고, 자동으로 실행되는 웹브라우저에서 확인이 가능하다.


  • 빌드
npm run build
를 입력하면 리액트 폴더의 내용물이 압축되어 웹상에 올리기 적합한 형태로 build 폴더 안에 생성 된다.

serve -s build
를 입력한다면 build 폴더의 내용물을 볼 수 있는 서버가 생성된다. 중지는 Ctrl+C를 통해 할 수 있다.


5.2. yarn[편집]


  • 설치
Node.js를 설치해서 npm이 함께 설치되게 한 다음에 프로젝트를 만들 폴더의 터미널에서
npm i -g yarn
을 입력한다. (Yarn 설치)

yarn create react-app .
을 입력한다. (점까지 모두 입력되어야 한다.)


만일 다른 이름으로 프로젝트를 만들고자 한다면
yarn create react-app [Project name]
을 입력한다.

참고로 yarn를 이용한 설치는 npm -g 처럼 노드 환경을 사용하는 pc 자체에 깔리는 것이 아니고 node module이 설치된 프로젝트 내부에만 설치되는 것도 아니다. create-react-app은 처음 프로젝트를 생성할 때만 필요하고 그 이후에는 있을 필요가 없기 때문에 yarn를 사용해 1회성으로 설치 후 자동 삭제된다.

참고로 자바스크립트가 아닌 타입스크립트를 사용하려면
yarn create react-app . --template typescript
를 입력하면 된다.


  • 실행
yarn start
를 터미널에서 입력하면 리액트가 실행된다. 실행을 종료하고 싶다면 Ctrl+C를 터미널에서 누르면 된다.

실행되면 리액트 폴더의 src/app.js 파일을 통해 페이지 수정을 하고, 자동으로 실행되는 웹브라우저에서 확인이 가능하다.


  • 빌드
yarn build
를 입력하면 리액트 폴더의 내용물이 압축되어 웹상에 올리기 적합한 형태로 build 폴더 안에 생성 된다.

serve -s build
를 입력한다면 build 폴더의 내용물을 볼 수 있는 서버가 생성된다. 중지는 Ctrl+C를 통해 할 수 있다.


6. React Native[편집]



6.1. 개요[편집]


React의 문법으로 안드로이드, iOS 앱을 개발할 수 있는 프레임워크이다. React를 배웠던 개발자라면 몇시간만에 익숙해질 수 있을만큼 React와 거의 유사한 문법을 가지고 있으며, 실제로 차이나는 부분은 브라우저의 HTML Element를 사용하는 것이 아니라 View, Text 등의 자체 태그를 사용하는 점과 CSS를 사용하지 않고 오직
CreateStyleSheet
를 이용한 스타일만 지원하고, 일부 속성이 가감되었다는 것 정도. 현재는 웹과 동일한 CSS요소 사용을 위한 Styled Component 및 PostCSS를 지원하므로 웹개발자나 퍼블리셔도 무리없이 UI구성이 가능하다.


6.2. 지원 플랫폼[편집]


  • 공식 지원 플랫폼
    • Android
    • iOS
    • tvOS
    • Windows#
    • macOS#[3]

  • 비공식 지원
    • 타이젠
    • 리눅스 [4]

거의 모든(Windows Phone을 제외한) 플랫폼을 지원한다.


6.3. 다른 라이브러리와의 비교[편집]


사실상 크로스 플랫폼은 React Native와 Flutter가 양분하고 있다고 봐도 된다. 따라서 Flutter와 비교를 위주로 서술한다.

앱스토어 심사없이 UI와 function을 업데이트할 수 있는 Code Push 기능을 공식적으로 지원하는 플랫폼은 하이브리드와 크로스플랫폼 전체를 통틀어 React Native가 유일하기 때문에 큰 장점이라 볼 수 있다. Flutter도 존재는 하지만, 서드파티 라이브러리이며 버전이 낮기에 신뢰도가 낮다.[5]

Flutter 는 React Native와 비슷한 성격을 가지고 있으나[6] JavaScript가 아닌 구글의 Dart언어를 사용한다. 패키지의 수는 React Native가 더 많지만, 페이스북의 성향은 대부분의 기능들을 서드파티로 사용하라에 가깝고, 구글은 대부분은 공식에서 지원해준다는 것에 가까워서 직접적인 비교는 힘들다.

플러터와 비교했을 때 프레임 드랍 문제가 존재한다. 이를 해결하기 위해 Flutter가 Skia로 렌더링하듯이 React Native Skia 가 개발되고 있다.

아이러니하게도 React Native 프로젝트를 관리하고 있는 Meta에서는 자사 앱 개발을 React Native가 아닌 안드로이드와 iOS 네이티브로 하고 있다.

ionic이 버전5 부터 React를 지원하기 시작했다. 기존 ionic 생태계의 플러그인인 cordovacapacitor를 적절히 조합하여, 네이티브 기능을 선택적으로 제공할 수 있게 되었다.

6.4. 크로스 플랫폼(?)[편집]


크로스 플랫폼은 맞다. 그러나 단순히 하나의 코드가 Android, IOS 등 다양한 플랫폼에 맞게 추가적인 노력을 들이지 않아도 알아서 척척 다 해주는 것이라고 착각하여 함부로 적용하는 것은 조심해야 한다. 개발자 자신들도 그렇지만 개발자를 고용하는 입장에서도 더욱 주의해야 한다.

특히나 영세한 업체에서 Android, IOS 개발자를 각각 모시기도 힘들고 2명을 쓰는것이 큰 부담이라고 생각하여 React Native 개발자 한명만 뽑으면 되지 않겠느냐고 단순히 접근하는 경우가 많은데 일반적인 쇼핑몰 수준까지는 어느 정도 가능할 수 있다. 그러나 네이티브한 기능을 사용할때 큰 문제가 된다. React Native 개발자가 Android, IOS 네이티브 앱 개발을 하지 못할 경우 해당 기능은 그냥 못한다고 보면 된다.

예를 들어 카카오 로그인 기능을 넣는다고 하자. 카카오에서 React Native 모듈을 지원해주지 않는다면, Android와 IOS 네이티브 코드를 각각 작성해야만 한다. 거기에 모듈을 사용하다 네이티브한 코드를 변경할 일이 생기거나 업데이트를 한다면 어떻게 대응할 것인가?

필요한 모듈을 별로 고민해보지 않고 사용하는 개발자 혹은 PM들이라면 전혀 신경을 쓰지 못했을 수 있으나 이 위험성을 간과하지 말아야 한다. 네이버 지도 API의 경우도 React Native 지원 모듈을 공식이 아니라 오픈 소스 개발자들이 지원해주고 있다. 카카오의 경우도 마찬가지이며, 적지 않은 오픈소스 모듈들은 미구현된 기능들도 많고 업데이트되는 기능을 따라가지 못하기도 한다. UI를 구현할 때도 네이티브로 건들지 않고서는 구현하기 껄끄러운 것들을 지원하는 React Native 모듈이 없다면 그 UI는 만들지 못하는 것이다.

이 상황이 가장 와닿는 예시로, VAN사를 통한 카드 결제 기능을 사용하는 앱을 개발한다고 가정해 보자. VAN사에서는 아직도 C++, C\#, C 모듈만 제공하는 곳이 많으며 조금 신경쓰는 곳마저 Java 정도를 지원할 뿐이고 JavaScript를 지원하는 곳은 더욱이 적다. 자, React Native만 다룰줄 아는 개발자에게 이러한 대체할 수 없는 외부 모듈을 반드시 사용하라고 한다면 bridge[7]를 구현해낼 수 있을까?

물론 Android, IOS 개발자가 준비되어 있고 유지보수가 잘 되는 탄탄한 기업은 오히려 네이티브 앱에서 React Native로 갈아타기도 한다. 왜냐하면 한번 정식 버전 출시 후에는 큰 변경이 없는 마이너한 업데이트가 대부분이며 이럴 경우에는 React Native로 갈아타며 얻는 생산성이 좋기 때문.


7. React를 사용하는 웹 사이트/프로그램[편집]




8. 여담[편집]


현재는 전혀 관련없는 이야기이지만 초기 라이선스는 특이한 BSD + Patent 라이선스였으며[9], 핵심은 페이스북에 특허 소송을 제기하는 순간 React 사용권한을 상실한다는 내용이었다. 페이스북 측은 React의 보호를 위해 특별히 만든 라이선스라고 했지만 오히려 페이스북 측이 React를 인질삼아 React를 핵심으로 개발한 서비스의 특허를 무단으로 사용하기 위함이라는 의혹까지 생겨났을 정도였으니. 때문에 아파치 재단에서는 아예 React 라이선스가 적용된 소스코드의 사용을 금지한다고 발표했으며 오픈소스 생태계에서 배제되는 사건이 발생했었다. 이후 지금의 MIT 라이선스로 리라이선싱 되면서 사건은 종료.

전자정부표준프레임워크의 차기 베타 버전과 함께 샘플 프로젝트를 공개적으로 제공하는데, 그 중 프론트엔드 샘플 프로젝트가 바로 이 리액트다. 비록 샘플일 뿐이지만, 시스템 통합 생태계를 생각하면 전자정부 프레임워크 4.0의 기본 템플릿에 포함되어 있어서 프론트엔드 생태계가 기울어질 가능성을 배제할 수 없다.


파일:크리에이티브 커먼즈 라이선스__CC.png 이 문서의 내용 중 전체 또는 일부는 2023-11-02 18:05:09에 나무위키 React(라이브러리) 문서에서 가져왔습니다.

[1] xml 문법[2] 이 부분이 의외로 큰 차이가 있는 게, 객체의 프로퍼티를 읽을 때 Optional chaining을 사용해서 객체 a의 프로퍼티 b를 a?.b로 안전하게 불러올 수 있다. 해당 기능이 지원되지 않는 AngularVue.js는 a && a.b 같이 상위 객체의 null 여부를 일일이 검증해야 한다.[3] 어째서인지 메타애플도 아닌 마이크로소프트가 개발하고 있다.[4] 지원 종료 #[5] 이 부분은 trade-off라고 할 수 있다. Flutter는 네이티브 코드로 미리 컴파일 되기 때문에 속도가 빠른 대신 코드 푸시가 불가능한 것이고 리액트 네이티브는 속도가 희생되는 대신 자바스크립트 코드만 서버에서 따로 푸시해주면 앱 상에서는 자바스크립트 런타임에서 실시간으로 컴파일하며 돌아가는 것이기 때문이다. 그러나 Flutter 개발 시 사용하는 언어인 Dart는 JIT 컴파일와 AOT 컴파일 모두 지원하기 때문에 기술적으로 불가능하지는 않다. 다만 공식 지원 계획이 없고 있다 하더라도 속도가 희생될 뿐이다.[6] 그럴 수밖에 없는 것이 플루터 자체가 리액트 네이티브를 참고하여 만들어진 것이기 때문이다.[7] Turbo Native Modules로 개선하고 있다고는 해도 네이티브 구현이 간단하지 않은 것은 여전히 마찬가지이다.[8] 업데이트시 뜨는 알림창과 오픈소스 라이센스 열람으로 알 수 있다[9] BSD 라이선스 자체는 문제가 없다. 괜히 상당량의 오픈소스가 BSD 아니면 MIT인게 아니다.

관련 문서