[React.JS] 강좌 3편 JSX


이 튜토리얼은 2018년에 새로운 강의로 재작성되었습니다 [새 튜토리얼 보기]

liste

이번 강좌에서는 React.js 에서 사용되는 JSX 문법에 대하여 알아보겠습니다. React.js 는 일반 JavaScript 문법이 아닌 JSX 문법을 사용하여 UI를 템플릿화 합니다. JSX를 사용하는것이 필수는 아니지만 이를 사용하면 다음과 같은 장점이 있습니다.

  • JSX는 컴파일링 되면서 최적화 되므로, 빠르다
  • Type-safe (어떠한 연산도 정의되지 않은 결과를 내놓지 않는것, 즉 예측 불가능한 결과를 나타내지 않는 것 [출처: jerrypop 블로그]) 하며 컴파일링 과정에서 에러를 감지 할 수 있다.
  • HTML에 익숙하다면, JSX를 사용하여 더 쉽고 빠르게 템플릿을 작성 할 수 있다.

1. JSX 사용하기

JSX는 HTML이랑 거의 비슷하게 생겼습니다. 저번강좌에서 작업환경을 설정 할 때도 App.js 에서 JSX가 사용되었는데요 한번 다시 봐볼까요?

App.js

import React from 'react';

class App extends React.Component {
    render(){

        return (
                <h1>Hello Velopert</h1>
        );
    }
}

export default App;
  • LINE 1: import 는 ES6 에 도입된 새로운 문법인데, var React = require(‘react’) 와 같습니다. React 모듈은 Component를 만들때 사용됩니다.
  • LINE 3: class 개념 역시 ES6 에 새로 도입된 요소중 하나 입니다. 모든 Component는 React.Component 를 상속합니다. ES5 환경에서는 React.createClass() 라는 메소드를 사용합니다.  또한, ES5 에서 클래스를 만들때는 메소드들을 nest 할 수 없고 prototype을 사용했어야 했는데, 많이 편해졌죠. ES6 Class 에 대해서는 Mozilla 참고자료 에서 확인하세요.
  • LINE 4: render() 메소드에서는 컴포넌트에 렌더링 될 데이타를 정의합니다.
  • LINE 5~7이 부분이 JSX의 가장 중요한 부분입니다. 보시면, 자바스크립트에서 html 태그를 반환하는데, 따옴표같은건 없죠? React JSX 는 XML-like Syntax 를 native Javascript로 변환해줍니다.  따라서 ” ” 로 감싸지 않는 점 주의하시구요, ( ) 를 사용하지 않아도 오류는 발생하지 않지만 가독성을 위하여 사용하는것이 좋습니다.

확장자에 대하여..

JSX 파일의 확장자의 경우, 이전에는 개발자들이 .jsx 확장자를 사용하였지만 요즘은 .js 를 사용하는 추세로 전환되어 가고 있습니다. 페이스북의 오픈소스 에디터인 draftjs 는 구별을 제대로 하기 위하여 .react.js 확장자를 사용하기도 합니다. 이 강좌에서는 .js 확장자를 사용하도록 하겠습니다.

JSX VS JS

JSX 를 사용했을 때 와 사용하지 않았을 때를 비교해보고싶다면 다음 링크들을 클릭해보세요.

2. Nested Elements

컴포넌트에서 여러 Element 를 렌더링 해야 할 때, 그 element들을 필수적으로 container element 안에 포함시켜줘야됩니다.
예를들어 다음과 같이 코드를 작성하면:

        return  (
            <h1> Hello Velopert</h1>
            <h2> Welcome </h2>
        );

변환 과정에서 다음과 같은 오류가 발생합니다.

ERROR in ./src/App.js
Module build failed: SyntaxError: /home/vlpt/node_tutorial/react/react-tutorials/03-jsx/src/App.js: Adjacent JSX elements must be wrapped in an enclosing tag (10:12)
   8 |         return  (
   9 |             <h1> Hello Velopert</h1>
> 10 |             <h2> Welcome </h2>
     |             ^
  11 |         );
  12 |     }
  13 | }

다음과 같이 div element 를 wrapper 로 사용하면 오류가 발생하지 않습니다.

        return  (
            <div>
                <h1> Hello Velopert </h1>
                <h2> Welcome </h2>
            </div>
        );

3. JavaScript Expression

JSX 안에서, JavaScript 표현을 사용하는 방법은 매우 간단합니다. 그냥 { } 로 wrapping 하면 됩니다.

    render(){
        let text = "Dev-Server"
        return  (
            <div>
                <h1> Hello Velopert </h1>
                <h2> Welcome to {text}</h2>
            </div>
        );
    }
  • LINE 2: ES6 에 도입된 let 키워드는 var 과 비슷하지만, var 변수의 scope는 기본적으로 함수 단위인데 let 은 블럭 범위 내에서 변수를 선언합니다. 따라서 가끔 발생하는 javascript 의 Scope관련 문제를 해결 할 수 있습니다. 지금 이 상황에선 let 을 사용하는것이 필수는 아니지만, ES6 에선 평상시 let 을 쓰고 var은 필요한 상황에서만 사용하는게 좋습니다. let 에 관련된 정보는 Mozilla 참고자료 에서 더 읽어보세요.
  • LINE 6: { text } 를 사용하여 text Javascript 변수를 렌더링합니다.

 

임의 method 생성 및 사용하기

React 에서 method를 생성하고 사용하는 방법에 대하여 알아보겠습니다.

    sayHey(){
       alert("hey");
    }

    render(){
        let text = "Dev-Server"
        return  (
            <div>
                <h1> Hello Velopert </h1>
                <h2> Welcome to {text}</h2>
                <button onClick={this.sayHey}>Click Me</button>
            </div>
        );
    }
  • LINE 11:  {this.sayHey} 를 통해 버튼이 클릭되면 해당 메소드가 실행되게 할 수 있습니다.  () 가 뒤에 안붙어있다는점을 주의해주세요. 만약에 () 가 붙으면 페이지가 로드 될때도 실행되고, 클릭할때도 실행됩니다.

If-Else 문 사용 불가

JSX 안에서 사용되는 JavaScript 표현에는 If-Else 문이 사용 불가합니다. 이에 대한 대안은 ternary ( condition ? true : false ) 표현을 사용하는 것입니다.
예:  <p>{1 == 1 ? 'True' : 'False'}</p>

4. Inline Style

React의 Inline Style 에서는, string 형식이 사용되지 않고 key 가 camelCase 인 Object 가 사용됩니다.
한번 예제를 통하여 배워봅시다.

    render(){
        let text = "Dev-Server";

        let pStyle = {
            color: 'aqua',
            backgroundColor: 'black'
        };

        return  (
            <div>
                <h1> Hello Velopert </h1>
                <h2> Welcome to {text}</h2>
                <button onClick= {this.sayHey}>Click Me</button>
                <p style = {pStyle}>{1 == 1 ? 'True' : 'False'}</p>
            </div>
        );
    }

pStyleelement 에 적용되었습니다.

5. 주석

JSX 안에서 주석을 작성할 때엔, { /* comments */ } 형식으로 작성하면 됩니다. 여기에 작성된 주석은 브라우저상 source 에서 나타나지 않습니다.

주의하실 점은 2. Nested Element 에서 나왔던 것 처럼 container element 안에 주석이 작성되어야 합니다.

6. Naming Convention

모든 React Component 은 첫 문자가 대문자인 CamelCase 로 작성됩니다.

 

마무리하며..

출력물

캡처

JSX 의 기본적인 형식을 알아보았습니다.

이 강좌에서 사용된 코드는

다음 강좌에서는 Component 에 대하여 자세히 알아보도록 하겠습니다.

liste

  • qvil

    안녕하세요. 강의 정말 잘 보고있습니다! 궁금한 점이 있는데요
    React에서 class나 render 메쏘드 _sayHey 메쏘드 등의 중괄호 끝에 세미콜론을 붙이지 않는 이유가 있나요?
    테스트 해봤는데 세미콜론 붙여도 정상동작하는데 혹시 실무에서 사용하는 디자인패턴이라던가 다른 이유가 있는지 궁금합니다. 🙂

    • 저는 그 부분에 대하여 생각해본적이 없어서 한번 검색을 해봤는데요

      클래스에서 ; 가 붙어도 오류가 안나는이유는

      http://exploringjs.com/es6/ch_classes.html
      를 참고하시면

      Semicolons are allowed, but ignored:

      Semicolons are allowed in preparation for future syntax which may include semicolon-terminated members

      라고 나와있네요. 그 세미콜론은 사용해도 오류는 안나고, ES6에서 트랜스파일과정에서 무시되며, 다음 자바스크립트 문법에서 semicolon으로 끝나는 멤버를 지원을 하기 위한 준비를 위해서 허용이 된다고 하네요.

      지금은 클래스 멤버변수를 만들때 클래스선언을 하고 그 하단에서 하거나 (App.foo = 1 이런 식) constructor 에서 해야하는데 나중에는 클래스내부에서

      foo = 1; 이렇게 할 수 있을 것같아요.

      정리를 해드리자면, 디자인 패턴이 따로있는건 아니구 semicolon은 메소드 뒤에 붙이는 용도가 아니다 가 되겠네요~

      즐거운 공부되세요~~

  • 배준경

    강의 감사합니다~!
    궁금한게 있는데요 ES6에서 import로 불러오는 것과 var React = require(‘react’)와 차이가 있는건가요???

    • 아직 ES6 를 지원하지 않는 브라우저들을 호환시키기 위해 저희는 babel 을 통하여 ES6 문법을 ES5 로 변환합니다.
      그래서 결국 성능면에서는 똑같습니다.

  • Nununana

    역시친절한벨로퍼트님이시네여

  • qvil

    궁금한 점이 있습니다.
    임의 method 생성 및 사용하기 에서
    LINE 1: Component 가 상속하는 메소드가 아닌 임의 메소드라는걸 확실하게 명시하기 위하여 메소드 이름을 _ 로 시작하는것을 권장합니다.
    라고 하셨는데, 뒤에 나오는 강의에서 handleClick 같은 상속받지 않는 메소드에 왜 _를 붙이지 않는지 혹시 다른 이유가 있는지 궁금합니다.

    • 질문해주셔서 감사합니다 😀

      React 를 처음 시작할때쯤엔 그렇게 임의메소드는 _ 로 시작하는 컨벤션을 따르고있었는데 나중에가선
      이 스타일이 권장되지 않는것을 알게되어 _ 를 없앴습니다. (https://github.com/airbnb/javascript/tree/master/react#methods)
      혼동을 방지하기 위하여 게시글을 수정하였습니다.

  • Hyun

    굉장히 간결하고 이해하기 쉽게 강좌를 올려주셔서 편하게 학습하고 있습니다.

    LINE 11: {this.sayHey} 를 통해 버튼이 클릭되면 해당 메소드가 실행되게 할 수 있습니다. () 가 뒤에 안붙어있다는점을 주의해주세요. 만약에 () 가 붙으면 페이지가 로드 될때도 실행되고, 클릭할때도 실행됩니다.

    이부분이 특이해서 저도 직접 실험해보기 위해 코드에 ()를 넣고 실행해보았더니 페이지가 로드될 때 실행이 되고, 클릭할때는 실행이 되지를 않습니다. 최근에 스펙이 변경된걸까요? 확인해보고 저와 같이 실행이 되지 않는다면 저부분을 수정하셔야 할 것 같습니
    다.

    • Wonkun Kim

      ()를 사용하게 되면 onClick 이벤트 핸들러가 불렸을 때 해당 함수의 리턴 값 (이 상황에서는 undefined)를 실행하므로 아무 일도 일어나지 않는 것이 맞습니다.

  • pury

    안녕하세요 이번에 React를 처음 공부하고 있습니다.
    다름이 아니라 codepen이 아니라 sublime에서 따라하고 싶은데 babel 패키지를 설치하고 따라하는데
    파일을 jsx 코드가 있는 js 파일과 html 파일을 만들어서 html파일에서 js를 불러오는 방식으로 할려 했는데 생각처럼 실행이 안되네요. type 도 text/babel로 했는데 어떤 다른 설정을 해야하는건가요?

  • Hanjoong Cho

    유익한 강좌 잘 보고 있습니다. 감사합니다 ^^

  • JIYUN park

    헉 너무 감사해여~!~!~!~! 책샀는데 책하나도 안되는데 !!!!!!! 이거 따라하니까 잘 되네요!!!!!! 감사합니당

  • Wonkun Kim

    강좌 잘 보고 있습니다. 소스 코드에 라인 넘버가 있으면 좋을 것 같습니다.

  • 장주호

    혹시 atom 에디터 쓰시는건가요? atom 에디터를 사용중인데, js 파일에서 html 테그에 색을 입혀주지 않아서요. 어떤 패키지를 깔아야 하나요?

  • hb

    안녕하세요 질문이 있습니다.
    카멜케이스란 “각 단어의 첫문자를 대문자로 표기하고 붙여쓰되, 맨처음 문자는 소문자로 표기함” 이라고 정의 되어있는데요
    리액트 컴퍼넌트는 대문자로 시작해야 하는데
    대문자로 시작하는건 PascalCase 가 아닌가요?