리액트JS로 웹 서비스 만들기 2일차

2018. 4. 21. 02:36Programming/ReactJS

이제 간단한 Hello World를 출력해보겠습니다.

루트 폴더(my-app) 밑에는 node_modules, public, src 폴더가 있는데요.

이 중에서 우리가 편집할 부분은 src 폴더입니다.

 

src 폴더 안에 App.js, index.js, registerServiceWorker.js가 있는데,

index.js는 일종의 메인 메소드로 보면 됩니다. 이게 호출되면서 그 안에 쓰여진 다른 메소드도 연쇄적으로 호출되는 것이죠.

 

1
2
3
4
5
6
7
8
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';
 
ReactDOM.render(<App />document.getElementById('root'));
registerServiceWorker();
cs

 

index.js를 보시면 자바와 유사하게 위에 import문이 있고,

밑에 함수 호출 부분이 있는데 ReactDOM.render라는 것이 보입니다.

 

ReactDOM은 리액트로 쓰여진 부분을 웹사이트에 DOM 모델을 이용해서 그려주는 모듈로, render 함수를 실행하면 App이라는 컴포넌트가 웹 페이지 위에 그려지게 됩니다.

 

그럼 App이 어떠한 내용을 담고 있는지 살펴 보도록 하죠.

App은 컴포넌트 클래스를 상속하고 있는 클래스입니다.

처음 상태를 보면 <div className="App"> 아래에 여러 가지 요소가

잔뜩 써져 있는 것을 볼 수 있습니다.

 

여기서 div 안에 내용을 전부 다 지우고 Hello World!만 남깁시다.

이것으로 Hello World 출력은 끝입니다. 간단하죠?

그럼 App 컴포넌트에 대해서 좀 더 설명해 보도록 하겠습니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import React, { Component } from 'react';
import './App.css';
 
class App extends Component {
  render() {
    return (
      <div className="App">
        Hello World!
      </div>
    );
  }
}
 
export default App;
cs

 

 

위에 코드를 보면 아시겠듯이 render라는 함수를 갖고 있으며 이 함수는 <div> 태그를 리턴합니다.

 

또한 맨 밑을 보시면 export default App이라는 것이 있는데요. export는 import(가져오다)의 반의어입니다. 가져오다의 반대이니 남에게 준다는 의미가 있습니다.

만약에 export를 쓰지 않으면 어떻게 될까요?

 

 

 

위와 같은 에러가 뜹니다. 여기서 에러가 뜨는 곳은 index.js인데,

index.js에서 App을 import할 때 문제가 생겼다는 것이죠. 여기에서 우리는 export는 해당 클래스를 다른 클래스에서 import할 수 있게 해주는 것임을 유추할 수 있습니다.

 

Hello World를 출력한 시점에서 본격적으로 웹 서비스를 만들기 시작합니다.

외부 API에서 가져온 영화 정보를 리스트로 출력하는 것이 이번의 목표인데요.

일단은 간단하게 리액트의 기본적인 문법을 익혀보도록 하겠습니다.

 

일단 src 폴더 아래에 Movie.js 파일을 생성합시다.

참고로 이 Movie.js 파일은 영화 정보를 담아 표시해주는 컴포넌트입니다.


과제1) Movie 컴포넌트 안에 This is movie component라는 문장을 담아서 웹사이트에 출력해 봅시다.


#App.js


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import React, { Component } from 'react';
import './App.css';
import Movie from './Movie';
 
class App extends Component {
  render() {
    return (
      <div className="App">
        <Movie />
      </div>
    );
  }
}
 
export default App;
 
cs


#Movie.js


1
2
3
4
5
6
7
8
9
10
11
12
import React, {Component} from 'react';
 
class Movie extends Component {
  render(){
    return (
      <h1>this is movie component</h1>
    );
  }
}
 
export default Movie;
 
cs



Movie 컴포넌트를 HTML 태그 사용하듯이 넣어줌으로써

Movie 컴포넌트 안의 내용이 웹페이지에 나타나게 됩니다.


과제2) App에 ready player one이라는 영화 제목을 변수로 선언한 다음에 그것을 Movie 컴포넌트에 넘겨서 웹페이지에 출력해 봅시다.


힌트) 컴포넌트 간의 데이터 이동에는 props라는 것을 사용합니다.


#App.js


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import React, { Component } from 'react';
import './App.css';
import Movie from './Movie';
 
const movie = {
  title: 'ready player one'
}
 
class App extends Component {
  render() {
    return (
      <div className="App">
        <Movie title={movie.title}/>
      </div>
    );
  }
}
 
export default App;
 
cs



#Movie.js


1
2
3
4
5
6
7
8
9
10
11
12
13
import React, {Component} from 'react';
 
class Movie extends Component {
  render(){
    console.log(this.props);
    return (
      <h1>{this.props.title}</h1>
    );
  }
}
 
export default Movie;
 
cs


App에서 Movie로 props를 전달할 때는,

<Movie title={movie.title}/>

위와 같은 식으로 HTML에서 속성(attribute)를 쓰듯이 props를 설정합니다.

이렇게 전달 받은 props는 this.props를 통해서 획득할 수 있습니다.


과제3) 넘겨줄 props에 영화 포스터(변수명: poster)를 추가하자.

또한 넘겨줄 영화 정보는 현재 1개에서 4개를 넘겨주도록 변경하자.


힌트) 자바스크립트에서 배열(array)와 오브젝트(object)를 작성하는 방식을 알아둘 것.

힌트) map 함수를 이용한 반복문에 대해서 알아둘 것. 또한 ES2015(ES6) 문법 중 하나인 Arrow 함수를 이용할 것.



#App.js


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
31
32
33
34
35
36
37
38
import React, { Component } from 'react';
import './App.css';
import Movie from './Movie';
 
const movie = [
  {
    title: 'ready player one',
    poster: 'http://sm.ign.com/ign_jp/review/r/ready-play/
ready-player-one-review_fyc1.jpg'
  },
  {
    title: 'matrix',
    poster: 'https://encrypted-tbn0.gstatic.com/images?q=
tbn:ANd9GcR-jMT2KVyuM6qMjeuyuJugg962ahFv62ee3HO4VbIZcj3q2Sq2'
  },
  {
    title: 'up',
    poster: 'https://encrypted-tbn0.gstatic.com/images?q=
tbn:ANd9GcR8F-fx5DCzmfpalo-gFFf9kBaF42q4PWvU9CmEeR-0RGBTXJ7Q'
  },
  {
    title: 'inside out',
    poster: 'https://lumiere-a.akamaihd.net/v1/images/take
over_insideout_b602f36b.jpeg?region=0,0,2048,856'
  }
]
 
class App extends Component {
  render() {
    return (
      <div className="App">
        {
          movie.map((movie, index) =>
          <Movie title={movie.title} poster={movie.poster} key={index}/>)
        }
      </div>
    );
  }
}
 
export default App;
 
cs



#Movie.js


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import React, {Component} from 'react';
 
class Movie extends Component {
  render(){
    console.log(this.props);
    return (
      <div>
        <h1>{this.props.title}</h1>
        <img src={this.props.poster}/>
      </div>
    );
  }
}
 
export default Movie;
 
cs



여기까지 했다면 영화 4개의 제목과 포스터가 웹페이지에 표시되게 됩니다.

아무런 도움 없이 혼자서 여기까지 다 해냈다면 대단하신 겁니다.

저 또한 처음부터 하진 못 하고 강의 보고 따라했었으니까요. 특히 map이나 화살표 함수 같은 경우 처음 접하면 이게 뭐지? 하실 거라고 봅니다.


작성하다보면 몇 가지 에러가 발생했을 텐데요.

그 중 하나는 wrapping 에러인데 JSX의 경우 계층 구조를 이루어야 합니다.

그래서 가장 위 계층에 태그가 2개가 되어버리면 아래와 같은 에러가 뜹니다.

두 태그를 div로 감싸주시면 에러가 해결 가능합니다.



아래 경고문은 에러가 아니지만 일단 짚고 넘어가겠습니다. key prop 경고문인데요. 

배열의 요소들은 각각 유니크한 키값을 가져야 한다는 의미입니다.

저 같은 경우 array의 index(0, 1, 2, 3)를 키값으로 부여하여 경고문이 나오지 않게 했습니다. 사실 이 경고는 무시하더라도 컴파일하는 데는 큰 문제는 없지만, 신경이 쓰이니 해결해 주도록 합시다.



일단 2일차는 여기까지 하고 3일차에서 계속 이어나가도록 하겠습니다.

수고하셨습니다~