React.js JSX Syntax

React.js JSX 문법

React.js 는 일반 JavaScript 문법이 아닌 JSX 문법을 사용하여 UI를 템플릿화 한다. JSX를 사용하는것이 필수는 아니지만 이를 사용하면 다음과 같은 장점이 있다.

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

type-safe 란
“어떠한 오퍼레이션(또는 연산)도 정의되지 않은 결과를 내놓지 않는것, 즉, 예측불가능한 결과를 내지 않는것을 뜻한다.”

예를 들면, 1 + “1” 의 연산이 가능하거나, 문자열에 숫자 1을 할당하는것이 가능하다거나 한다는 것은 일면 비 논리적이라고 볼 수 있다.

type-safe 란 위와 같이 연산이나 조작에 있어서 논리적이지 않은 것에 대해 엄격히 체크를 하여
Runtime시 이로 인한 오류가 발생하지 않도록 하는것이다.

Type-Safe하다고 알려진 언어에서는 보통 이를 컴파일 타임에 에러처리를 해주지만,
Type-Safe하지 않은 언어, 예를 들어 자바스크립트같은 언어에서는 이것을 적당하게(?) 처리한다.
그래서 Javascript는 Type-Safe하다고 하지 않는다.

위와 같은 의미에서, 일반적으로, c# / java 와 같은 언어들을 일반적으로 type-safe 하다라고 한다.

JSX 사용하기

JSX는 HTML이랑 문법이 거의 비슷하게 생겼다.

App.js

1
2
3
4
5
6
7
8
9
10
11
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로 변환해주므로 "" 로 감싸지 않는 점을 주의해야한다. ()를 사용하지 않아도 오류는 발생하지 않지만 가독성을 위하여 사용하는것이 좋다.

1. 확장자에 대하여..

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

JSX VS JS
JSX 를 사용했을 경우와 사용하지 않았을 때를 비교 차이는 다음과 같다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<!-- JSX -->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JSX 문법</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.24/browser.js"></script>
<script src="https://npmcdn.com/react@latest/dist/react-with-addons.js"></script>
<script src="https://npmcdn.com/react-dom@latest/dist/react-dom.js"></script>
<script src="https://facebook.github.io/react/js/jsfiddle-integration-babel.js"></script>
</head>
<body>
<div id="container">
<!-- This element's contents will be replaced with your component. -->
</div>

<script>
var Hello = React.createClass({
render: function() {
return <div>Hello {this.props.name}</div>;
}
});

ReactDOM.render(
<Hello name="World" />,
document.getElementById('container')
);
</script>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<!-- JS -->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS 문법</title>
<script src="https://npmcdn.com/react@latest/dist/react-with-addons.js"></script>
<script src="https://npmcdn.com/react-dom@latest/dist/react-dom.js"></script>
</head>
<body>
<div id="container">
<!-- This element's contents will be replaced with your component. -->
</div>

<script>
var Hello = React.createClass({
displayName: 'Hello',
render: function() {
return React.createElement("div", null, "Hello ", this.props.name);
}
});

ReactDOM.render(
React.createElement(Hello, {name: "World"}),
document.getElementById('container')
);
</script>
</body>
</html>

2. Nested Elements

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

1
2
3
4
return (
<h1> Hello Velopert</h1>
<h2> Welcome </h2>
);

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

1
2
3
4
5
6
7
8
9
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 로 사용하면 오류가 발생하지 않는다.

1
2
3
4
5
6
return (
<div>
<h1> Hello Velopert </h1>
<h2> Welcome </h2>
</div>
);

3. JavaScript Expression

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

1
2
3
4
5
6
7
8
9
10
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를 생성하고 사용하는 방법에 대하여 알아보자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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 ) 표현(삼항 연산자)을 사용하는 것이다.

예를 들면 다음과 같다.

1
<p>{1 == 1 ? 'True' : 'False'}</p>

4. Inline Style

React의 Inline Style 에서는, string 형식이 사용되지 않고 key 가 camelCase 인 Object 가 사용된다.
다음 예제를 통하여 살펴보자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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>
);
}

pStyle 이 p element 에 적용되었다.

5. 주석

JSX 안에서 주석을 작성할 때엔, { /* comments */ } 형식으로 작성하면 된다. 여기에 작성된 주석은 브라우저상 source 에서 나타나지 않는다. 주의하실 점은 2. Nested Element 에서 나왔던 것 처럼 container element 안에 주석이 작성되어야 한다.

6. Naming Convention

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

참조

공유하기