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
39
40
41
42
43
44
45
46
import React, { Component } from 'react';
import './App.css';
import Movie from './Movie';
 
 
const movies = [
  {
    title:"완벽한 타인",
    poster:"http://www.newsinstar.com/data/photos/20180937/art_15367158497873_e15bff.jpg"
  },
  {
    title:"보헤미안 랩소디",
    poster:"http://image.cine21.com/resize/cine21/poster/2018/0518/12_06_54__5afe434e1f297[H800-].PNG"
  },
  {
    title:"창궐",
    poster:"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcS9te4ZPkCjmfMbzua__AogoVkO8_pSQg_k9HLioQM6B2lPPnix7w"
  },
  {
    title:"암수살인",
    poster:"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTKpaFaBzed4mShvSJPVD2vQf4W618DFT8OFa-KNAPTuJLTWi5x"
  },
  {
    title:"미쓰백",
    poster:"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcT53iAJpVivS5RAVVNB_MoEs_a6sTOcbv2tA2XhNgz6ovcj6Yeq"
  }
]
 
class App extends Component {
  render() {
    return (
      <div className="App">
      {console.log(movies)}
        {movies.map(movie =>{
            console.log(movie)
            var a= <Movie title={movie.title} poster={movie.poster} />
            
          return a;
        })}
      </div>
    );
  }
}
 
export default App;
 
cs



movies 를 Json 타입으로 만들고 출력을 해보니  배열에 들어가있다. length 또한 5로 나온다. 




map을 사용하여 movies 를 movie로 리스트를 만들어서 다시 찍어보니까  object만 출력이됨 ㄷㄷ





고로 movies[0].title , movies[1].title  이렇게 해줄 이유가 없음 


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
39
40
41
42
import React, { Component } from 'react';
import './App.css';
import Movie from './Movie';
 
 
const movies = [
  {
    title:"완벽한 타인",
    poster:"http://www.newsinstar.com/data/photos/20180937/art_15367158497873_e15bff.jpg"
  },
  {
    title:"보헤미안 랩소디",
    poster:"http://image.cine21.com/resize/cine21/poster/2018/0518/12_06_54__5afe434e1f297[H800-].PNG"
  },
  {
    title:"창궐",
    poster:"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcS9te4ZPkCjmfMbzua__AogoVkO8_pSQg_k9HLioQM6B2lPPnix7w"
  },
  {
    title:"암수살인",
    poster:"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTKpaFaBzed4mShvSJPVD2vQf4W618DFT8OFa-KNAPTuJLTWi5x"
  },
  {
    title:"미쓰백",
    poster:"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcT53iAJpVivS5RAVVNB_MoEs_a6sTOcbv2tA2XhNgz6ovcj6Yeq"
  }
]
 
class App extends Component {
  render() {
    return (
      <div className="App">
        {movies.map(movie =>{
          return <Movie title={movie.title} poster={movie.poster} />
        })}
      </div>
    );
  }
}
 
export default App;
 
cs

 

출력해보자 동일하게 잘 출력됨 





Props는 상태  상태에서 가장중요한것은  부보 즉 상위에서부터 하위로 값을 넘겨준다


고로 App -> Movie -> MovieImage 순으로 ~


APP에 영화 제목과 이미지를 설정하고 화면에 출력해보자


* 참고로 문화생활을 하지 않는 나에겐 특정 영화와 관련이 없음 .. 


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
import React, { Component } from 'react';
import './App.css';
import Movie from './Movie';
 
const title = [
    "완벽한 타인",
    "보헤미안 랩소디",
    "창궐",
    "암수살인",
    "미쓰백"
]
 
const poster = [
  "http://www.newsinstar.com/data/photos/20180937/art_15367158497873_e15bff.jpg",
  "http://image.cine21.com/resize/cine21/poster/2018/0518/12_06_54__5afe434e1f297[H800-].PNG",
  "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcS9te4ZPkCjmfMbzua__AogoVkO8_pSQg_k9HLioQM6B2lPPnix7w",
  "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTKpaFaBzed4mShvSJPVD2vQf4W618DFT8OFa-KNAPTuJLTWi5x",
  "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcT53iAJpVivS5RAVVNB_MoEs_a6sTOcbv2tA2XhNgz6ovcj6Yeq"
]
 
class App extends Component {
  render() {
    return (
      <div className="App">
        <Movie title={title[0]} poster={poster[0]} />
        <Movie title={title[1]} poster={poster[1]} />
        <Movie title={title[2]} poster={poster[2]} />
        <Movie title={title[3]} poster={poster[3]} />
        <Movie title={title[4]} poster={poster[4]} />
      </div>
    );
  }
}
 
export default App;
 
cs

Movie.js


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



각각 이미지에 맞는 제목이 잘 출력됨 




컴포넌트를 다시 복습해보자 




Component 안에 Component 또 그안에 Component를 넣는 방식이다 . 


영화이미지와 영화 제목을 반복해서 만들고 싶다. 어떻게 해야할까 ~ 


Movie 컴포넌트를 만들어서 영화 제목을 넣어두고 MovieImage 컴포넌트를 만들어서 Movie 컴포넌트에 넣어주고 


최종적으로 Movie 컴포넌트를 APP에다 넣어주면 된다. 


Movie.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
import React, { Component } from 'react';
 
class Movie extends Component {
    render() {
        return (
            <div>
                <MovieImage />
                <h1>영화 제목</h1>
            </div>
        );
    }
}
 
class MovieImage extends Component{
    render() {
        return(
            <div>
                <img src="http://www.newsinstar.com/data/photos/20180937/art_15367158497873_e15bff.jpg" />
            </div>
        );
    }
}
 
export default Movie;
cs



MovieImage.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';
 
class App extends Component {
  render() {
    return (
      <div className="App">
        <Movie />
        <Movie />
        <Movie />
        <Movie />
        <Movie />
      </div>
    );
  }
}
 
export default App;
 
cs


<Movie />
        <Movie />
        <Movie />
        <Movie />
        <Movie />


5번 반복해주니 같은 화면이 5번 반복해서 출력된다.  페이스북처럼 카트방식은 이런식으로 반복 해서 만들어지는 것이다.  참 페북 개발자들 대단한듯 ㄷㄷㄷㄷ




Component 를 시작하기전에 


다음 그림부터 보자


parent 는 지금까지 작성한 App.js 일것이고 추가로 이제 component 를 만들어 볼것인데 그전에 


props와 state에 대해 간략하게 알고가자


말그대로 속성과 상태이다


쉽게 설명하면 



parent 는  백지도화지라고 가정하면 

각각 component 를 덕지덕지 붙여서 하나의 화면을 만든다 ~ 라고 생각하면 될듯


밑에 그림을보면

portfolio 부모 컴포넌트라고 생각하고 

Navbar 컴포넌트 

jumbotron 컴포넌트

contents 컴포넌트

footer 컴포넌트





이렇게 각각 컴포넌트 별로 만들어서 붙이면됨

그리고 앞서 공부한 css로 이쁘게 꾸며주면



이런식으로 그림이 나오는것이다.


위 Navbar에서 Home / About / Gallery / Contact 를  porps라고 생각하자   


우측에 로그인은 state 라고 생각하자


로그인을하면 logout으로 상태를 바꾼다


이런식으로 정적인것을 props  동적인것을 state 라고 생각하면 쉽지만 


무조건 props가 정적이다는 아니다. ... 


(부모 state에서 자식 porps로  자식 컴포넌트에서 특정 이벤트가 발생할 때 부모 메서드를 호출하면 

props 도 유동적으로 사용할 수 있다 하지만 우선 개념을 이해하기 위해선 쉽게 가자)













리액트에 CSS 를 적용하기 위해서는  이런식으로 작성했겠죠 리액트는 더더욱 간단함


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
<!DOCTYPE html>
<html>
<head>
<style>
body {
    background-color: lightblue;
}
h1 {
    color: white;
    text-align: center;
}
{
    font-family: verdana;
    font-size: 20px;
}
</style>
</head>
<body>
 
<h1>My First CSS Example</h1>
<p>기본 html 기초</p>
 
</body>
</html>
cs




리액트는  { } 안에 넣으면됨 


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
import React, { Component } from 'react';
import './App.css';
 
class App extends Component {
  render() {
 
    const myname = '왕초보코딩탈출';
 
    const style = {
 
      backgroundColor : 'red',
      border: '1px solid black',
      
 
    }
    
    return (
    <div style={style} >
    
      <h6>안녕하세요 나의 이름은 {myname} 입니다.</h6>
      <h6>잘 부탁드립니다.~~~</h6>
 
    </div>
    );
  }
}
 
export default App;
 
cs


여기서 중요한 것은 


기존에는           background-color: lightblue;

리액트에서는     backgroundColor : 'red',


조금 차이가 있음 


camelCase 를 써야함


camelCase란 말그대로 탁타표기법으로 낙타 등처럼 울퉁불퉁 


camelCase 요런식


  • 각 단어의 첫문자를 대문자로 표기하고 붙여쓰되, 맨처음 문자는 소문자로 표기함
  • 띄어쓰기 대신 대문자로 단어를 구분하는 표기 방식



CSS import 해서 사용하기


조금 차이가 있음 APP.css를 수정하시거나 추가로 css 파일을 하나 만들서 수정합니다.

 




1
2
3
4
.div1 {
  background-color: skyblue;
  font-size: 20px;
}
cs



App.js 에 파일을 임포트합니다.

className 을 설정하시면 됩니다.


import './App.css';


<div className="div1">
    <p>css 파일 import</p>
</div>



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
import React, { Component } from 'react';
import './App.css';
 
class App extends Component {
  render() {
 
    const myname = '왕초보코딩탈출';
 
    const style = {
 
      backgroundColor : 'red',
      border: '1px solid black',
      
 
    }
    
    return (
    <div>
      <div style={style} >
        <h6>안녕하세요 나의 이름은 {myname} 입니다.</h6>
        <h6>잘 부탁드립니다.~~~</h6>
      </div>
      <div className="div1">
        <p>css 파일 import</p>
      </div>
    </div>
    );
  }
}
 
export default App;
cs






JSX 내부에서는 if문을 사용할 수 없음 


그렇다면 어떻게 조건문을 사용할 수 있을까??


{ } 안에 연산자를 사용하면됨 ㅎ


매우매우 간단함


state 가 true 일 때 참입니다.

login 이 false 일 때 로그인을 하세요


&& 를 사용할 수 도 있다. true 면 보여주고 그렇지 않으면 렌더링 해도 보여주지 않는다


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
39
40
41
42
43
import React, { Component } from 'react';
import './App.css';
 
class App extends Component {
  render() {
 
    const myname = '왕초보코딩탈출';
 
    const state = true;
 
    const login = false;
 
    const display = true;
    
    return (
    <div>
      <h6>안녕하세요 나의 이름은 {myname} 입니다.</h6>
      <h6>잘 부탁드립니다.~~~</h6>
 
      <h2>
      {
        state ? '참 입니다.' : '거짓 입니다.'
      }
      </h2>
      <h2>
      {
        login ? '로그인 되었습니다..' : '로그인을 하세요'
      }
      </h2>
      <h2>
      {
        display && '아하하하하' 
      }
      </h2>
 
    </div>
    );
  }
}
 
export default App;
 
 
cs



로그인했을 때와 안했을 때 화면을 다르게 하거나 권한별로 페이지를 다르게 보여주거나 뭐 그럴때 써봐야겠다.~


리액트가 처음엔 어려웠으나 어찌보면 좀 쉬운것 같기도하네요 아닌가?ㅎㅎㅎㅎ여튼 열심히해봐야겠다



평일엔 ㅠㅠ 기초를 좀 다지고 주말에 속도를 내야겠다 ㅠㅠ




JSX에 DOM 요소를 렌더링 하는 하는 방법 중 


스크립트 표현식을 사용해보자 



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import React, { Component } from 'react';
import './App.css';
 
class App extends Component {
  render() {
 
    const myname = '왕초보코딩탈출';
    return (
    <div>
      <h1>안녕하세요 나의 이름은 {myname} 입니다.</h1>
      <h2>잘 부탁드립니다.~~~</h2>
    </div>
    );
  }
}
 
export default App;
 
cs



myname에 왕초보코딩탈출 이라고 선언하고


JSX 코드 내에 { }로  감싸서 표현하면 됨





프로젝트 생성 시 만들어졌던 페이지를 수정해보자 


프로젝트

   src -> App.js 를 수정해보자


1
2
3
4
5
6
7
8
9
10
11
12
13
14
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
 
class App extends Component {
  render() {
    return (
     <h1>리액트를 시작해보자</h1>
     <h2>리액트</h2>
    );
  }
}
 
export default App;
cs


이렇게 하면 에러를 발생시킨다 ..


이유는 h1 , h2 두개의 요소가 1개의 부모 요소를 가지고 있지 않아서 에러를 발생시킨다 ..


그래서 div로 둘러준다 ~


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
 
class App extends Component {
  render() {
    return (
    <div>
      <h1>리액트를 시작해보자</h1>
      <h2>리액트</h2>
    </div>
    );
  }
}
 
export default App;
 
cs


그리고 yarn start 로 실행해보자



리액트 v16 이상에서는 Fragment컴포넌트가 추가되어  div로 감싸지 않고 여러 요소를 렌더링 하고싶다면


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import React, { Component , Fragment} from 'react';
import logo from './logo.svg';
import './App.css';
 
class App extends Component {
  render() {
    return (
    <Fragment>
      <h1>리액트를 시작해보자</h1>
      <h2>리액트</h2>
    </Fragment>
    );
  }
}
 
export default App;
cs


다음과 같이 작성해서 실행하면 된다.~





ES5 와 ES6 비교 



꼭 알아야하는 이유는 구버전의 브라우저에서는 ES6를 지원하지 않기때문 ..?


https://es6console.com/


왼쪽 패널에서 ECMAScript 6 문법으로 코드를 작성하고 변환을 누르면 자동으로 오른쪽 패널에 ECMAScript 5 문법으로 변환된 코드를 표시해줍니다.


우선 간단하게 몇개만 확인해보자 


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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
 
//es5 문법
 
function greetings (name) {
 
 return 'hello ' + name
 
}
 
 
//es6 문법
 
const greetings = (name=> {
 
 return `hello ${name}`;
 
}
 
 
 
//es5 문법
 
var obj1 = {a : 1, b : 2
var obj2 = {a : 2, c : 3, d : 4
var obj3 = Object.assign (obj1, obj2)
 
 
//es6 문법
 
const obj1 = {a : 1, b : 2
const obj2 = {a : 2, c : 3, d : 4
const obj3 = {... obj1, ... obj2}
 
 
 
//es5 문법
 
var obj1 = { a: 1, b: 2, c: 3, d: 4 }
var a = obj1.a
var b = obj1.b
var c = obj1.c
var d = obj1.d
 
//es6 문법
 
const obj1 = { a: 1, b: 2, c: 3, d: 4 }
const {
  a,
  b,
  c,
  d
= obj1
 
 
 
 
//es5 문법
var a = 1
var b = 2
var c = 3
var d = 4
var obj1 = { a: a, b: b, c: c, d: d }
 
//es6 문법
var a = 1
var b = 2
var c = 3
var d = 4
var obj1 = { a, b, c, d }
 
 
 
//es5 문법
function isGreater (a, b, cb) {
  
  var greater = false
  if(a > b) {
    greater = true
  }
  cb(greater)
}
isGreater(12function (result) {
  if(result) {
    console.log('greater');
  } else {
    console.log('smaller')
  }
})
 
//es6 문법
 
const isGreater = (a, b) => {
 return new Promise ((resolve, reject) => {
  if(a > b) {
   resolve(true)
  } else {
   reject(false)
  }
 })
}
isGreater(12)
 .then(result => {
    console.log('greater')
 })
 .catch(result => {
    console.log('smaller')
 })
 
//es5 문법
var myModule = { x: 1, y: function(){ console.log('This is ES5') }}
module.exports = myModule;
//es6 문법
const myModule = { x: 1, y: () => { console.log('This is ES5') }}
export default myModule;
 
//es5 문법
var myModule = require('./myModule');
//es6 문법
import myModule from './myModule';
import {x, y, z} from './myModule';
 
cs


코드가 매우 간결해지고 가독성도 좋아지고 좋음 



웹팩에대하여 


향후에 웹팩 옵션 수정 할 때 다시 자세하게 알아보기하고 Webpack이 뭐하는지만 일단 알아보자


https://webpack.js.org/


사이트에 들어가보면 메인에




나 또한 웹팩설정에 대하여 아직 잘 모른다 ㅎㅎ 

위에 이미지만 딱 봤을 때 아 ~ 어떤 느낌인지 


설정도 잘은 모르겠지만 

무엇을 어떻게 묶어서 어떻게 내보내고 불러올지 설정하지 않을까... 


bundle your assets  


JS , .png ,sass , jpg 등등   웹팩으로 딱 묶는 거구나 !!!



내가 기존에 작성했던 HTML 을보면



페이지마다 스크립트 또는 CSS 다 불러와야하고 그나마 include를 써서 하긴했다만 그것도 페이지별로 다르니 

필요없는 스크립트를 브라우저에서 로딩하게되고 불필요한 자원을 낭비하게 된다.....


그래서 webpack을 사용하는 것 아닐까?





CSS는  css-loader 가 


FILE 은 file-loader 가


여기서 한가지 알아야 할 것은 


최신 브라우저는 대부분 ES6 형태를 실행 가능하지만 구버전에서는 실행할 수 없기 때문에 ES5로 변환해줘야한다.


import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';


다음과 같은 import 는 ES6문법이다.


ES6 문법으로 작성 되어진 JS 코드들을 ES5로 변경해야한다 


이것을 가능하게 해주는 것이 Babel-loader 일단 웹팩에 대해서는 이정도로 알고 나중에 설정할 때 더 알아보기로 하자


자세하게 알아보려면 사이트 들어가서 Documentation 읽어보세요 ㅎㅎ 





+ Recent posts