게시글

5만명이 선택한 평균 별점 4.9의 제로초 프로그래밍 강좌! 로드맵만 따라오면 됩니다! 클릭
강좌2 - React - 8년 전 등록 / 6년 전 수정

React Component, JSX

안녕하세요. 이번 시간에는 React 컴포넌트를 직접 만들어보겠습니다. ES2015 문법을 사용할 거니깐, 잘 모르시면 ES2015 강좌를 먼저 보고 오세요! ES2015는 꼭 익혀두어야 합니다. 2~3년 후에는 대부분 ES2015를 사용하고 있을 거니깐요. 특히 BabelJS를 보셔야 ES2015 코드를 자바스크립트로 변환할 수 있습니다.

기초적인 컴포넌트입니다.

basic.js

import React, { Component } from 'react';

export default class Basic extends Component {
  renderSeparate() {
    return (
      <div>코드를 분리합시다</div>
    );
  }
  render() {
    return (
      <div>
        <span>저는 컴포넌트입니다!</span>
        <span>독립 만세!</span>
        <span>재사용 만세!</span>
        {this.renderSeparate()}
      </div>
    );
  }
}

react 모듈로부터 Component를 상속받는 Basic 클래스를 만들었습니다. Component를 상속받아야 이 코드가 리액트 컴포넌트임을 자바스크립트 엔진이 알 수 있습니다. Basic이 이 컴포넌트의 이름입니다. 마지막 render 메소드부터 봅시다. Component에는 render 메소드가 있는데 이 메소드가 반환하는 게 실제로 보여지는 DOM이 됩니다.

잠깐, 자바스크립트인데 html이 들어있죠? 문자열도 아니고 생 HTML입니다. 이상하죠? 저도 처음에 이 이상한 문법에 적응하느라고 힘들었습니다. JSX라고 불리는 문법입니다. 이 자바스크립트 파일 하나가 독립적인 컴포넌트 임무를 수행해야 하므로 자바스크립트 코드와 HTML 코드가 같이 있습니다. 사실 자바스크립트 코드로 완전히 HTML 코드를 대체할 수 있지만, 별로 추천하고 싶지는 않습니다. 가독성이 떨어지거든요.

JSX를 사용할 때는 몇 가지 알아두셔야 할 점이 있습니다. 컴포넌트는 반드시 하나의 노드로부터 시작해야 합니다. 위의 예시에서는 span 3개가 div로 감싸져 있습니다. 꼭 div일 필요는 없지만, 컴포넌트는 반드시 하나의 태그로 감싸져 있어야 합니다. 이게 단점이기도 합니다. React 16부터는 이 문제가 해결되었습니다. 아래와 같이 하면 됩니다. 대신 각각의 요소에 키를 주도록 합시다.

return [
  <div key="a">A</div>,
  <div key="b">B</div>
];

리액트 16.2부터 이렇게도 가능합니다. import React, { Component, Fragment } from 'react'를 한 후,

return (
  <Fragment>
    <div>A</div>
    <div>B</div>
  </Fragment>
)

개인적으로는 배열보다는 Fragment를 쓰는 것이 깔끔해보입니다.

또, 속성 명으로 자바스크립트처럼 camelCase를 사용해야 하고요. 만약 img 같이 태그 안에 내용이 없는 경우 꼭 />로 닫아주어야 합니다. 그리고 class가 아니라 className을 사용하셔야 한다는 거 잊지 마세요! (class는 자바스크립트에서 예약어이기 때문에 className으로 대체되었습니다. 비슷한 예로, label의 for 속성은 htmlFor로 대신합니다.)

조건문을 안에 넣을 수도 있습니다. 대신 if문이 아니라 삼항 연산자를 사용해야 합니다. 아래의 예시에서는 condition을 만족하면 className이 imageHighlight가 되고, 아닌 경우에는 image가 됩니다. 또한 condition을 만족할 경우에만 button을 렌더링합니다. 종합해서 한 예시로 보여드리겠습니다. onClick이 camelCase인 것에 주의하세요!

return (
  <div>
    <img src="주소" className={condition ? 'imageHighlight' : 'image'} />
    {condition && <button onClick={this.onClickButton}>클릭</button>}
  </div>
);

다시 원래 코드로 돌아가서 보면, span 3개 밑에 renderSeparate 함수를 호출하는 부분이 있네요. 이제 renderSeparate 메소드를 보죠. renderSeparate함수는 똑같이 JSX를 return하지만 아래의 render 메소드에서처럼 실행을 시켜야만 render됩니다. 이렇게 코드를 분리해 특정한 조건에만 render한다든지 할 수 있습니다.

사실 위처럼 간단한 코드는 class를 사용하지 말고 간단한 함수로 만드는 게 낫습니다. 특히 render 메소드밖에 없는 경우 주로 이렇게 함수로 만듭니다.

const renderSeparate = () => <div>코드를 분리합시다</div>;
export default const Basic = () => {
  return (
    <div>
       <span>저는 컴포넌트입니다!</span>
       <span>독립 만세!</span>
       <span>재사용 만세!</span>
       {renderSeparate()}
    </div>
  );
};

class로 만들었든 함수로 만들었든 간에 만들어진 컴포넌트는

<Basic />

이렇게 부모 컴포넌트에서 사용할 수 있습니다. ES2015의 모듈 시스템을 사용하면 한 컴포넌트당 파일 하나를 만들어서 효율적으로 관리할 수도 있습니다! 컴포넌트가 export default 구문으로 export되는 게 보이시죠?

이렇게 만든 basic.jsrender.js에서 import하고 바벨로 render.js를 컴파일합니다.

render.js

import Basic from './basic';
import { render } from 'react-dom';

render(<Basic />, document.getElementById('root'));

render.js를 보면 root 아이디를 가진 태그에 Basic 컴포넌트를 넣는 것을 볼 수 있습니다. react.html을 만들어서 #root 태그와 바벨로 컴파일 된 render.js를 넣고 실행해봅시다.

react.html

<html>
<body>
  <div id="root"></div>
  <script src="./render.js"></script>
</body>
</html>

지금까지 JSX 문법과 간단한 컴포넌트에 대해서 알아봤는데요. 컴포넌트가 정적이라 재미가 없네요. 다음 강좌에서는 컴포넌트를 동적으로 만드는 propsstate에 대해 알아보겠습니다!

조회수:
0
목록
투표로 게시글에 관해 피드백을 해주시면 게시글 수정 시 반영됩니다. 오류가 있다면 어떤 부분에 오류가 있는지도 알려주세요! 잘못된 정보가 퍼져나가지 않도록 도와주세요.
Copyright 2016- . 무단 전재 및 재배포 금지. 출처 표기 시 인용 가능.
5만명이 선택한 평균 별점 4.9의 제로초 프로그래밍 강좌! 로드맵만 따라오면 됩니다! 클릭

댓글

6개의 댓글이 있습니다.
6년 전
script src로 실행시켯는데 왜 화면에 아무것도 안뜨는지 모르겟네요 ㅠ
같은 폴더에 두고 실행시켯는데요..
6년 전
바벨 돌리셨나요??
6년 전
아하 근데... render.js를 컴파일 했더니 \u003cBasic /> 이부분에서 맨앞 \u003c이부분이 SyntaxError: render.js: Unexpected token (4:7) 이렇게 뜨네요 ㅠ
6년 전
바벨에서 jsx 문법을 허용하는 옵션이 있습니다. 그것도 켜주셔야 합니다 ㅠㅠ
6년 전
애구 성공했네요 ㅋㅋㅋ 감사합니다 ㅠㅠ
6년 전
바벨로 컴파일 하는 이유가 궁금합니다.
6년 전
jsx는 유효한 자바스크립트 문법이 아니기 때문입니다. 바벨 말고 타입스크립트로 컴파일하는 방법도 있습니다.
6년 전
바벨로 컴파일하는 과정이 자세히 써있지 않아서, (제가 무작정 뛰어들어서) 조금 헷갈리는 것 같습니다. 바벨 컴파일 과정을, 귀찮으시겠지만 한 스텝만 설명해 주실 수 있으실지요?

bebel render.js -o render1.js 로 바꾼 후,
node render1.js 를 하면,
SyntaxError: Unexpected token import 오류가 발생합니다 ㅠㅠ

참고로 AWS cloud9 환경에서 실행하고 있습니다.
6년 전
아아 노드에서 실행하는 건 아니고요. 바벨로 js 파일 만든 후, 브라우저에 script src로 넣는 것입니다. 리액트는 프론트입니다
6년 전
아 알것같습니다 리액트 자체로는 아무것도 띄울 수 없군요 그리구 저도 node 교과서 샀습니다 리액트 교과서도 만들어주세요 ㅋㅋㅋ
6년 전
그리고 .babelrc같은 설정 파일이 필요한데 제 ecmascript강좌의 바벨 강좌 보시면 됩니다. @babel/preset-react가 있으면 jsx 컴파일 됩니다.
6년 전
정말 별거아니지만 오타! '반든' => '만든'!
6년 전
감사합니다~
7년 전
return (
\u003cdiv>
\u003cimg src="주소" className={condition ? 'imageHighlight' : 'image'} />
{condition && \u003cbutton onClick={this.onClickButton}>클릭\u003c/button>
\u003c/div>
);

에서 {condition --> {condition} 이 되어야 하는 건가요?
}이 하나 빠져있는데 어디에 들어가야 할지 궁금합니다.
7년 전
버튼 닫는 태그 뒤에 들어가야합니다
7년 전
아 그렇군요! 감사합니다 :)
8년 전
basic.js를 node basic.js로 실행했을 때 Unexpected token import 에러가 난다면 어떤것을 안해준걸까요?
8년 전
저건 클라이언트 코드라서 노드로는 돌릴 수 없어요~
8년 전
요즘 공부중에 Angular 와 React 와 고민하다가 React로 정했습니다. 헌데 view 영역에서 특화된 라이브러리라하던데 React와 궁합이 잘 맞는 Control, Model 영역을 하는 라이브러리는 어떤게 있는지 궁금합니다.
8년 전
React는 MVC 패턴 말고 Redux패턴을 사용합니다.