함께 성장하는 프로독학러

1. React Component, JSX 본문

Programming/react.js

1. React Component, JSX

프로독학러 2018. 4. 17. 17:53

안녕하세요, 프로독학러입니다.


이번 포스팅 부터 React.js 에 대해서 알아가 보도록 하겠습니다.


가장 먼저 배울 내용은 React Component 입니다.


React 프로젝트는 컴포넌트 단위로 구성됩니다.

여러 개의 컴포넌트 들이 모여 페이지를 구성하게 됩니다.

컴포넌트 별로 파일을 만들어 사용하기 때문에 한 번 정의한 컴포넌트를 프로젝트 내의 다른 곳에서 재사용하기도 편리합니다.


그럼 저희의 프로젝트에서 컴포넌트를 하나 만들어 보도록 하겠습니다.


루트 폴더의 하위 src 폴더의 아래에 components 폴더를 하나 만들어 보겠습니다.

(앞으로 만들 컴포넌트들은 모두 이 폴더에 저장할 것입니다)

그리고 생성된 components 폴더에 Test_comp.js 파일을 만들고 아래의 코드를 복사, 붙여넣기 해 주세요.


(./src/components/Test_comp.js)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import React, { Component } from 'react';
 
class Test_comp extends Component {
  render(){
    return(
      <div>
        <h1>test component</h1>
        <p>this is a test component</p>
      </div>
    )
  }
}
 
export default Test_comp;
 
cs


이제 이 코드를 하나하나 뜯어 보도록 하겠습니다.

먼저 코드의 첫 번째 줄은 외부로부터 react를 불러오는 코드입니다. (import는 ES6의 문법으로, 기존 자바스크립트의 require 와 같습니다)

react 를 불러올 때, React 와 Component 를 import 했습니다.

우리는 컴포넌트를 만들 때 Component 를 사용하면 됩니다.


코드의 세 번째 줄에서 Test_comp 라는 클래스를 정의 했습니다.

그리고 Test_comp 클래스는 Component 를 상속받습니다. (extends)

Component를 상속 받음으로 우리가 정의한 Test_comp는 컴포넌트가 됩니다.

*(ES6의 class에 대해서 익숙하지 않으신 분들은 아래의 링크를 참조해 주세요)

<ES6 class>


클래스를 정의한 스코프 안에는 render() 가 정의되어 있습니다. 

모든 컴포넌트는 이 속성을 가지고 있어야 합니다.

이는 컴포넌트가 어떻게 보여질 지를 결정합니다.

리턴값으로 브라우저에 어떻게 표시될지 정의되는데, 이는 HTML 태그처럼 보이지만, JSX 문법입니다.

JSX 문법에 대해서는 아래에서 좀 더 자세히 살펴보도록 하겠습니다.

지금단계에서는 HTML의 문법이라고 생각하고 보셔도 무방합니다.


코드의 14번째 줄에서 우리가 정의한 Test_comp를 export 하고 있습니다. (export는 ES6의 문법으로, 기존 자바스크립트의 module.exports 와 같습니다)


Test_comp.js 파일을 만들고 난 뒤에는, src 폴더 하위의 index.js 파일로 들어가 Test_comp 컴포넌트를 임포트 해 줘야 합니다.

index.js 파일은 웹팩을 설치할 때 엔트리파일로 지정한 파일입니다.

이는 어플리케이션의 관계(의존성 그래프)의 시작점으로, 웹팩은 엔트리파일을 기점으로 임포트 된 파일들을 찾아 여러 파일간의 관계성을 유지하며 번들링, 최적화를 합니다.

우리는 Test_comp 컴포넌트가 웹 브라우저에서 출력되게 하고 싶습니다.

이를 위해 index.js 파일을 아래의 코드처럼 수정합니다.


(./src/index.js)

1
2
3
4
5
6
7
8
9
10
11
12
13
import React from 'react';
import ReactDOM from 'react-dom';
 
import Test_comp from './components/test_comp';
 
const title = 'Is it working? hot module replacement...';
 
ReactDOM.render(
  <Test_comp />,
  document.getElementById('root')
);
 
module.hot.accept();
cs


코드의 네 번째 줄에서 위에서 만든 Test_comp 를 임포트 했습니다. (경로는 index.js 기준 경로이므로 위의 코드와 같이 표현됩니다)

그리고 8번째 줄의 ReactDOM.render 에서 첫 번째 인자를 <Test_comp /> 즉, 우리가 위에서 만든 Test_comp 컴포넌트를 주었습니다.

저장을 하고 터미널에서(루트파일 경로) npm start 를 통해 개발서버를 작동시키면, localhost:8080 에서 다음과 같이 Test_comp 에서 정의한 내용이 잘 렌더링 되는 것을 알 수 있습니다.



우리는 개발 환경을 설정 할 때 dist 폴더에 index.html 파일을 다음과 같이 정의 했었습니다.


(./dist/index.html)

1
2
3
4
5
6
7
8
9
10
11
<!DOCTYPE html>
<html>
  <head>
    <title>React Webpack Babel Setup</title>
  </head>
  <body>
    <div id="root"></div>
    <script src="/bundle.js"></script>
  </body>
</html>
 
cs


그리고 index.js 의 ReactDOM.render 메소드(8번째 줄)의 두 번째 인자에서 index.html 의 엘리먼트들 중 아이디가 'root' 인 엘리먼트를 렌더링할 타깃으로 정했습니다.

따라서, ReactDOM.render 메소드의 첫 번째 인자인 Test_comp 컴포넌트가 index.html 의 <div id='root'> 안에서 렌더링 된 것입니다.

이를 구글 개발자 도구에서 살펴보면 쉽게 알 수 있습니다.



간단하게 정리하자면, Test_comp 컴포넌트를 index.html 의 <div id='root'>안에 렌더링 하기 위해 엔트리파일인 index.js 파일에 임포트 해 렌더링 한 것입니다.

모든 컴포트의 임포트와 렌더링은 이러한 방식으로 이루어 집니다. 만약 Test_comp 안에 다른 컴포넌트를 포함하고 싶으면 포함하고 싶은 컴포넌트를 정의하고, 그를 Test_comp 에 임포트 하면 됩니다.


여기까지 컴포넌트의 정의와 렌더링 되는 방법에 대해 알아보았습니다.


그럼 이번에는 컴포넌트의 렌더링 속성에서 사용되는 JSX 문법에 대해서 알아보겠습니다.


JSX 문법은 위에서 본 바와 같이 HTML의 문법과 상당히 유사합니다.

JSX 는 컴포넌트를 정의 할 때 컴포넌트가 어떻게 렌더링 되는지 정합니다. (class 안의 render(){} 의 return 값)

기본적으로 HTML 문법을 그대로 사용할 수 있지만, 주의해야 할 몇 가지 사항들이 있습니다.


첫 번째는 컴포넌트에서 여러 Element 들을 렌더링 할 때, 렌더 속성의 리턴값(class 안의 render(){} 의 return 값)은 반드시 Container Element 안에 포함시켜야 합니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
import Test_comp from './components/Test_comp';
 
class JsxCaution_1 extends Component {
    ...
    render(){
        return(
            <div>
                <h1>JSX caution1</h1>
                <p>컴포포넌트에서 여러 엘리먼트들을 렌더링 할 때, 반드시 컨테이너 엘리먼트(div태그 등)안에 포함 되어 있어야한다.</p>
                <Test_comp />
            </div>
        )        
    }
}
cs


위의 코드에서 <div> 태그로 감싸지 않으면 오류가 발생할 수 있습니다.

따라서 렌더링 하는 부분에서 컨테이너 엘리먼트로 요소들을 감싸는 것을 잊지않고 해 줘야 합니다.


그리고 위의 코드의 10번째 줄에는 HTML 의 태그가 아닌 태그가 들어있습니다.

이는 리액트의 컴포넌트입니다. 코드의 첫 번째 줄에서 컴포넌트를 불러오고, 10번째 줄에서 사용한 것입니다.

이렇게 JSX 는 리액트 컴포넌트를 HTML 태그처럼 사용할 수 있도록 도와줍니다.


두 번째는 JSX 안에서 자바스크립트를 표현하는 방법입니다.

JSX 안에서 자바스크립트의 표현식을 사용할 수 있는데, 그 방법은 자바스크립트의 표현식을 { } 로 wrapping 하는 것입니다.\

즉, { } 안에서 자바스크립트의 표현식(변수, 함수 등)을 사용할 수 있습니다.


1
2
3
4
5
6
7
8
9
10
11
12
class JsxCaution_2 extends Component {
    ...
    render(){
        let text = 'JSX 안에서 자바스크립트를 사용하려면 {}를 이용해 wrapping 하라';
        return(
            <div>
                <h1>JSX caution1</h1>
                <p>{text}</p>
            </div>
        )        
    }
}
cs


위의 코드에서 return() 바깥에서 정의된 text를 { }을 이용하여 JSX 에서 사용하고 있습니다.

**{ }안에서 조건문을 사용하려면 if else 문을 사용하지 말고 ES6의 삼항 조건 연산자를 이용해야 한다.

ES6의 삼항 조건 연산자가 익숙하지 않으신 분은 아래의 링크를 참고해 주세요

<ES6 삼항 조건 연산자>


세 번째는 JSX안에서 스타일을 정의할 때(Inline style 정의) camel case 를 사용해야 한 다는 것입니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class JsxCaution_3 extends Component {
    ...
    render(){
        let style = {
            color:'aqua';
            backgroundColor:'black';
        }
        return(
            <div>
                <h1>JSX caution3</h1>
                <p style={style}>background-color가 아닌 backgroundColor로 </p>
            </div>
        )        
    }
}
 
cs


코드의 11번째 줄에서 인라인스타일을 정의 하고 있는데, 이 때 style 명을 camel case로 표기해야 합니다.

(background-color => backgroundColor )


네 번째는 JSX 안에서 주석을 사용하는 방식 것입니다.

주석은 {/* 주석내용 */} 과 같이 사용하는데, 여기서 주의 해야 할 것은, 주석 역시 컨테이너 엘리먼트 안에 위치해야 한다는 점입니다.

(div 등 컨테이너 태그 바깥에 위치하면 오류가 발생할 수 있다)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class JsxCaution_4 extends Component {
    ...
    render(){
        return(
            <div>
                {/* 주석은 이런 식으로 들어간다 */}
                {/* 멀티라인으로 
                    주석을 사용할 수 도 있다*/}
                <h1>JSX caution4</h1>
                <p>how to use comments</p>
            </div>
        )        
    }
}
 
cs


코드의 6, 7번쨰 줄과 같이 주석을 사용하면 됩니다.


지금까지 리액트의 기본 내용이라고 할 수 있는 컴포넌트와 JSX에 대해서 알아보았습니다.

다음 포스팅에서는 리액트에서 매우 중요한 개념 중 하나인 props에 대해서 알아보도록 하겠습니다.

감사합니다.


**참고 자료 (항상 감사드립니다)

https://velopert.com/reactjs-tutorials


*다녀가셨다는 표시는 공감으로 부탁드릴게요! (로그인 하지 않으셔도 공감은 가능합니다 ㅎㅎ)



Comments