1
2
3
4
1. create-react-app <projectName>
2. cd projectName
3. yarn start
 
cs


프로젝트를 생성하자 


App.js


(당일로 조회하면 데이터가 없다 그래서 하루 전 데이터를 조회하기위해 getData -1)을 했다.


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
import React, { Component } from "react";
import "./App.css";
import Movie from "./Movie";
 
const key = "발급받은 키";
 
const getDate = new Date();
const yDate = getDate.getTime(1 * 24 * 60 * 60 * 1000);
getDate.setTime(yDate);
var yYear = getDate.getFullYear();
var yMonth = getDate.getMonth() + 1;
var yDay = getDate.getDate() - 1;
 
if (yMonth < 10) {
  yMonth = "0" + yMonth;
}
if (yDay < 10) {
  yDay = "0" + yDay;
}
const resultDate = yYear + "-" + yMonth + "-" + yDay;
 
const res = resultDate.slice(010).replace(/-/g, "");
 
class App extends Component {
  state = {};
 
  componentDidMount() {
    this._getMovies();
  }
 
  _renderMovies = () => {
    const movies = this.state.movies.map((dailyBoxOfficeList, index) => {
      return (
        <Movie
          rank={dailyBoxOfficeList.rank}
          movieNm={dailyBoxOfficeList.movieNm}
          key={index}
        />
      );
    });
    return movies;
  };
 
  _getMovies = async () => {
    const movies = await this._callApi();
    this.setState({
      movies
    });
  };
 
  _callApi = () => {
    return fetch(
      `http://www.kobis.or.kr/kobisopenapi/webservice/rest/boxoffice/searchDailyBoxOfficeList.json?key=${key}&targetDt=${res}&itemPerPage=10`
    )
      .then(a => a.json())
      .then(json => json.boxOfficeResult.dailyBoxOfficeList)
      .catch(err => console.log(err));
  };
 
  render() {
    const { movies } = this.state;
    return (
      <div className={movies ? "App" : "App-loading"}>
        {movies ? this._renderMovies() : "로딩중 ..."}
      </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
import React, { Component } from "react";
import PropTypes from "prop-types";
import "./Movie.css";
 
function Movie({ rank, movieNm }) {
  return (
    <div className="Movie">
      <h1>
        {rank}위:{movieNm}
      </h1>
    </div>
  );
}
 
Movie.propTypes = {
  rank: PropTypes.string.isRequired,
  movieNm: PropTypes.string.isRequired
};
 
export default Movie;
 
cs



  {movies ? this._renderMovies() : "로딩중 ..."}


데이터가 있으면 보여주고 그렇지 않으면 로딩중이라고 처리를 한다.




순위랑 영화이름만 가져왔는데 추가로 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
                "rnum""1",
                "rank""1",
                "rankInten""0",
                "rankOldAndNew""OLD",
                "movieCd""20180290",
                "movieNm""아쿠아맨",
                "openDt""2018-12-19",
                "salesAmt""3482471050",
                "salesShare""33.8",
                "salesInten""1154445750",
                "salesChange""49.6",
                "salesAcc""33936773431",
                "audiCnt""384114",
                "audiInten""96420",
                "audiChange""33.5",
                "audiAcc""3875972",
                "scrnCnt""1158",
                "showCnt""4594"
cs


더 많은 데이터를 제공하니 수정해서 연습해봐야겠다.~


그리고 극한직업? 재밌나보다 보러가야겠다~ 



우선 

http://www.kobis.or.kr/kobisopenapi/homepg/user/openLogin.do


키를 발급받아야한다. 회원가입 후 키를 발급받자






Postman으로 json데이터를 확인해보자 


발급받은 키를 넣고 조회날, 몇위까지 표시할것인지,(최대 10개)





일별 박스오피스 데이터를 JSON으로 잘 가져온다  ㅎㅎ


다음에는 리액트로 데이터를 가져와서 뿌려보자









리액트로 웹을 공부하다가 CSS에 막혀서 ㅠㅠ 상대적으로 쉬운? React Navtive를 먼저 하기로 결정했다.


State, Props는 동일하나 Style는 생각보다 간단했다 . 


https://facebook.github.io/react-native/docs/style 


Layout 파트가 많지 않아서 .. 해보세요 










App.js


1
2
3
4
5
6
7
8
9
10
11
12
import React from "react";
import List from "./List";
import Input from "./TextInput";
//import { StyleSheet, Text, View } from "react-native";
 
const App = () => {
  //return <List />;
  return <Input />;
};
 
export default App;
 
cs



InputText.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
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
import React, { Component } from "react";
import {
  View,
  Text,
  TouchableOpacity,
  TextInput,
  StyleSheet
} from "react-native";
 
class Inputs extends Component {
  state = {
    email: "",
    password: ""
  };
 
  handleEmail = text => {
    this.setState({ email: text });
  };
 
  handlePassword = text => {
    this.setState({ password: text });
  };
 
  login = (email, pass) => {
    alert("email :" + email + "password :" + pass);
  };
 
  render() {
    return (
      <View style={styles.container}>
        <TextInput
          style={styles.input}
          underlineColorAndroid="transparent"
          placeholder="Email"
          placeholderTextColor="#9a73ef"
          autoCapitalize="none"
          onChangeText={this.handleEmail}
        />
        <TextInput
          style={styles.input}
          underlineColorAndroid="transparent"
          placeholder="Password"
          placeholderTextColor="#9a73ef"
          autoCapitalize="none"
          onChangeText={this.handlePassword}
        />
        <TouchableOpacity
          style={styles.submitButton}
          onPress={() => this.login(this.state.email, this.state.password)}
        >
          <Text style={styles.submitButtonText}>Submit</Text>
        </TouchableOpacity>
      </View>
    );
  }
}
 
export default Inputs;
 
const styles = StyleSheet.create({
  container: {
    paddingTop: 23
  },
  input: {
    margin: 15,
    height: 40,
    borderColor: "#7a42f4",
    borderWidth: 1
  },
  submitButton: {
    backgroundColor: "#7a42f4",
    padding: 10,
    margin: 15,
    height: 40
  },
  submitButtonText: {
    color: "white"
  }
});
 
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
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 코드 내에 { }로  감싸서 표현하면 됨




+ Recent posts