1. 고객 컴포넌트 만들기

src에 components디렉하나 만들어주고 그아래 Customer.js 파일을 만들어준다.

<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
import React, { Component } from "react";
import logo from "./logo.svg";
import "./App.css";
import Customer from "./components/Customer";
 
const customer = {
  name"들짐승",
  birthday: "112345",
  gender: "남자",
  job: "없음"
};
class App extends Component {
  render() {
    return (
      <Customer
        name={customer.name}
        birthday={customer.birthday}
        gender={customer.gender}
        job={customer.job}
      />
    );
  }
}
 
export default App;
 
cs

App.js에 고객변수 하나를 만들어주고 Customer에 속성으로 넘겨준다.

<Customer.js>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import React, {Component} from 'react';
 
class Customer extends Component{
    render(){
        return(
            <div>
                <h2>{this.props.name}</h2>
                <p>{this.props.birthday}</p>
                <p>{this.props.gender}</p>
                <p>{this.props.job}</p>
            </div>
        )
    }
}
 
export default Customer;
cs

 

Customer에서는 props로 받는다.

render부분을 보면

여러 태그들이 병렬로 나열돼있어서 <div>태그로 묶어줘야한다.

 

[리액트]props state

 

[리액트]props state

1. props props는 생성자 인자로 비유해서 이해했다. MyComponent 태그를 보면 속성=값 으로 인자를 넘겨줬다. 객체를 찍어낼때 생성자 인자로 "a", "b"를 넘겨줬다고 생각하면된다. 2.state state는 클래스의 pr..

fieldanimal.tistory.com

 

글고 동빈나형님이 개꿀팁 알려주셨는데

class Customer부분을 컨트롤+클릭하면

클래스 정의부로 자동으로 이동한다.

 

2. 고객 컴포넌트 쪼개기

<Customer.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
import React, { Component } from "react";
 
class Customer extends Component {
  render() {
    return (
      <div>
        <CustomerProfile
          id={this.props.id}
          name={this.props.name}
        ></CustomerProfile>
        <CustomerInfo
          birthday={this.props.birthday}
          gender={this.props.gender}
          job={this.props.job}
        ></CustomerInfo>
      </div>
    );
  }
}
class CustomerProfile extends Component {
  render() {
    return (
      <div>
        <h2>{this.props.id}</h2>
        <h2>{this.props.name}</h2>
      </div>
    );
  }
}
 
class CustomerInfo extends Component {
  render() {
    return (
      <div>
        <p>{this.props.birthday}</p>
        <p>{this.props.gender}</p>
        <p>{this.props.job}</p>
      </div>
    );
  }
}
 
export default Customer;
 
cs

 

Customer를 CustomerProfile이랑 CustomerInfo로 나눠서

각각 렌더링한다.

내부에서만 사용되는 클래스니깐 

export할땐 걍 Customer만 해주면된다.

 

3. 데이터 추가하기

<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
39
40
41
42
43
44
45
46
47
48
49
50
import React, { Component } from "react";
import logo from "./logo.svg";
import "./App.css";
import Customer from "./components/Customer";
 
const customers = [
  {
    id: 1,
    name"name1",
    birthday: "112345",
    gender: "남자",
    job: "없음"
  },
  {
    id: 2,
    name"name2",
    birthday: "112345",
    gender: "남자",
    job: "없음"
  },
  {
    id: 3,
    name"name3",
    birthday: "112345",
    gender: "여자",
    job: "없음"
  }
];
class App extends Component {
  render() {
    return (
      <div>
        {customers.map(c => {
          return (
            <Customer
              id={c.id}
              name={c.name}
              birthday={c.birthday}
              gender={c.gender}
              job={c.job}
            ></Customer>
          );
        })}
      </div>
    );
  }
}
 
export default App;
 
cs

map함수를 사용해서 조진다.

map안에 화살표함수가 있는데 익명함수쓸때 간단히 처리한다고 한다.

https://wayhome25.github.io/javascript/2017/02/23/js-Arrow-functions/

 

자바스크립트 화살표 함수 · 초보몽키의 개발공부로그

자바스크립트 화살표 함수 23 Feb 2017 | javascript 함수 화살표 함수 화살표 함수 (Arrow functions) 설명 화살표 함수 표현(arrow function expression)은 function 표현에 비해 구문이 짧고, 화살표 함수는 항상 익명입니다. 이 함수 표현은 메소드 함수가 아닌 곳에 가장 적당합니다. 그래서 생성자로서 사용할 수 없습니다. MDN 문법 (param1, param2, …, paramN) => { stat

wayhome25.github.io

var a = [
  "Hydrogen",
  "Helium",
  "Lithium",
  "Beryl­lium"
];

var a2 = a.map(function(s){ return s.length });

var a3 = a.map( s => s.length );

 

 

동빈나 개발자님의 리액트로 고객관리 시스템을 개발하는 강의가 있다.

https://www.youtube.com/watch?v=_yEH9mczm3g&list=PLRx0vPvlEmdD1pSqKZiTihy5rplxecNpz&index=1

 

https://ndb796.tistory.com/category/React%EC%99%80%20Node.js%EB%A1%9C%20%EB%A7%8C%EB%93%9C%EB%8A%94%20%EA%B3%A0%EA%B0%9D%20%EA%B4%80%EB%A6%AC%20%EC%8B%9C%EC%8A%A4%ED%85%9C%20%EA%B0%9C%EB%B0%9C%20%EA%B0%95%EC%A2%8C

 

'React와 Node.js로 만드는 고객 관리 시스템 개발 강좌' 카테고리의 글 목록

프로그래밍 강의를 진행하는 공간입니다.

ndb796.tistory.com

1. npx create-react-app management 로 프로젝트 만들어준다.

 

2. css 파일 바꿔서 적용시켜보기

App.css파일을 수정하고, App.js의 div에 적용시킨다.

JSX문법을 사용하기 때문에 걍 class=""가 아닌 className=""으로 적용시킨다.

 

 

 

2. README.md

깃허브에 올라가서 출력될 내용들, 소개내용,설치방법,레퍼런스 등이 들어가는 공간이다.

맨위에 한줄 추가해본다.

 

3. 원격저장소랑 연동시키기

일단 로컬저장소는 세팅이 되어있다.

https://fieldanimal.tistory.com/71?category=764530

 

[리액트]형상관리

create-react-app 하면서 앱 만들었을 때, 저절로 .git폴더가 안에 생겨져있었다. 로컬저장소까지 세팅이 된 상태다. 나는 생활코딩형님꺼 리액트 튜토리얼앱 다 만들고나서 한번에 commit, push 했다. commit할..

fieldanimal.tistory.com

실제로 추적하고있는게 보인다.

커밋한번 해주고

깃헙에 저장소 만들어주고

git remote add origin https://github.com/kimdongwoowoo/React-Management-System.git

git push origin master

아까 README.md에서 수정한 내용도 같이 나온다.

gitignore을 보면 npm module, build 다 업로드되지 않도록 처리되어있다. create-react-app 좋다.

' > 리액트' 카테고리의 다른 글

[리액트]고객관리 시스템_UI  (2) 2019.09.01
[리액트]고객관리 시스템_컴포넌트  (0) 2019.09.01
[리액트]형상관리  (0) 2019.08.31
[리액트]앱 빌드/배포  (0) 2019.08.31
[리액트]이벤트 핸들러  (0) 2019.08.31

create-react-app 하면서 앱 만들었을 때, 저절로 .git폴더가 안에 생겨져있었다.

로컬저장소까지 세팅이 된 상태다.

나는 생활코딩형님꺼 리액트 튜토리얼앱 다 만들고나서 한번에 commit, push 했다.

commit할때는 걍 visual studio code에서 메시지 입력하고 컨트롤엔터 쳐주면
내 로컬저장소에 변경된 파일들이 commit된다.

터미널에다가

  • 원격저장소를 등록시킬 때 : git remote add origin 깃헙주소
  • 원격저장소에 push할 때 : git push origin 브랜치이름 (master)

 

깃헙에 올리고 나니까

일케 돼있었다.

난 한번도 commit한 적이 없는데 맨 처음에 리액트플젝 만들 때 자동으로 로컬저장소에 커밋도 해줬나보다.

 

gitignore까지 있어서 안을 보니까

빌드한 부분은 제외하고 처리한다. 굉장히 스마트하다.

 

create-react-app할 때 깃세팅 다 해주고 vs code에서 쉽게 커밋해서그렇지
안그랬으면 해당 폴더(my-react-app) 들어가서 우클릭해서 git bash 키고
git init
해서 .git폴더 만들어주고 로컬저장소 세팅하고
git commit –m
메시지 해주고
git remote origin add
원격저장소주소하고

git push origin master해서 처리했어야 한다.

git ignore도 따로 했어야한다.

 

형상관리에 대한 작업들까지 생성해주는 프레임워크 짱이다.

' > 리액트' 카테고리의 다른 글

[리액트]고객관리 시스템_컴포넌트  (0) 2019.09.01
[리액트]고객관리 시스템_프로젝트 생성  (0) 2019.09.01
[리액트]앱 빌드/배포  (0) 2019.08.31
[리액트]이벤트 핸들러  (0) 2019.08.31
[리액트]props state  (0) 2019.08.31

생활코딩님의 리액트앱 배포용으로 빌드하는법 수업을 들었는데 아주 유용했다.

그냥 실행했을때

그냥 npm start로 앱을 실행했을때

디버깅 네트워크 탭에 들어가서 확인해보면 2.5MB나 갖고오고 있는걸 확인하고있다.

 

터미널에 npm build라고 치면 여러 작업을 거쳐 builld라는폴더가 하나 생긴다.
기존 프로젝트 내용들을 꽉꽉 줄여서 build폴더에 넣어놓은 모습이다.

index.html파일을 봐도 전혀 바뀌어있다.

빌드된 파일을 실행시키려면 어떻게 해야되는지도 나와있다.

serve를 npm으로 깔고 실행해야되는데

깔기 싫으면 그냥 npx serve -s build 해도 된다.

npm은 계속 설치해놓고 쓰는거고
npx
는 설치하고 사용하고 바로 지운다.

실행하면 알림메시지가 뜬다. 5000포트로 접속하면

빌드한 후

갖고온 파일 크기가 작아진게 보인다. 앱 열심히 만들고 배포할 때는 빌드를 해주면 된다.

' > 리액트' 카테고리의 다른 글

[리액트]고객관리 시스템_프로젝트 생성  (0) 2019.09.01
[리액트]형상관리  (0) 2019.08.31
[리액트]이벤트 핸들러  (0) 2019.08.31
[리액트]props state  (0) 2019.08.31
[리액트]컴포넌트  (0) 2019.08.31

 

자식컴포넌트에서 발생한 이벤트를 부모컴포넌트에서 핸들링하고싶을때가 있다.

 

1.부모컴포넌트에 핸들링함수를 만든다.

2.자식컴포넌트에 props로 넘겨준다.

3.자식컴포넌트에서 이벤트 발생시 해당 props 함수를 호출한다. 필요한 값은 인자로 넘기면 된다.

컴포넌트끼리 핸들링함수의 인자를 통해 연결된다.

<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
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
import React, { Component } from "react";
import logo from "./logo.svg";
import "./App.css"//일케해놓으면 App 컴포넌트가 로드될때 같이 import돼서 쓸수있게된다. 즉 <App/> 얘가 쓰일때
//css가 따라오게끔. 동적로드하는 효과.
import Subject from "./components/Subject";
import Content from "./components/Content";
import Article from "./components/Article";
import Controls from "./components/Controls";
import CreateForm from "./components/CreateForm"
import UpdateForm from "./components/UpdateForm"
class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      subject: { title: "WEB", desc: "world wide web!" },
      mode: "welcome",
      selected0,
      contents: [
        { id: 0, title: "HTML", desc: "HyperText Management Language" },
        { id: 1, title: "CSS", desc: "씨에스에스" },
        { id: 2, title: "javascript", desc: "자바스크립트" }
      ]
    
    };
  }
 
  getContent() {
 
    var _mode=this.state.mode;
    if (_mode === "read") {
      var article = this.state.contents[this.state.selected];
      return <Article article={article}></Article>;
    } else if (_mode === "welcome") {
      return <Article article={this.state.subject}></Article>;
    } else if(_mode==="create"){
      return <CreateForm addContent={this.addContent.bind(this)}></CreateForm>;
    } else if(_mode==="update"){
      return <UpdateForm data={this.state.contents[this.state.selected]} updateContent={this.updateContent.bind(this)}></UpdateForm>;
    }
  }
  addContent(title,desc){
    var len=this.state.contents.length;
    var newContents=Array.from(this.state.contents);
    newContents.push({id:len,title:title,desc:desc});
    this.setState({
      contents:newContents,
      mode:'read',
      selected:len
    })
  }
  updateContent(id,title,desc){
    var newContents=this.state.contents;
    newContents[id].title=title;
    newContents[id].desc=desc;
    this.setState({
      contents:newContents,
      mode:'read',
      selected:id
    });
  }
  changeMode(mode){
    this.setState({
      mode:mode
    });
  }
 
  changeArticle(i) {
    this.setState({
      mode:'read',
      selected: i
    });
  }
  render() {
    return (
      <div>
        <Subject
          title={this.state.subject.title}
          sub={this.state.subject.sub}
          onClicked={this.changeMode.bind(this)}
        ></Subject>
        <Content
          contents={this.state.contents}
          onClicked={this.changeArticle.bind(this)}
        ></Content>
        <Controls
          controls={this.state.controls} onClicked={this.changeMode.bind(this)}
        ></Controls>
        {this.getContent()}
      </div>
    );
  }
}
export default App;
 
cs

Content 컴포넌트를 사용할때, chageArticle 메서드를 넘겨준다.

이 때 bind를 해주는 이유는

자바스크립트에서 this키워드는 해당 객체를 나타내는게 아니라 어디서 호출되는가를 나타낸다.
changeArticle 메서드는 전역객체에서 호출되기 때문에 함수 내 코드에 this.setState의 this는 전역객체를 가리키게 된다.

당연히 전역객체에 state가 없기 때문에 오류가 난다.

이 메서드를 누가 호출 하는것 인가를 지정해줘야 한다.

bind(this)를 해주면 이 메서드는 호출될때 App컴포넌트 객체에서 호출된다는 뜻이 되어서

this.setState를 할 때 애가 App컴포넌트객체라고 생각하고 작동한다.

 

this랑 bind에 대한 개념은 이 형님이 잘 정리해 놓으셨다.

https://blueshw.github.io/2018/03/12/this/

 

https://blueshw.github.io/2018/03/12/this/

 

blueshw.github.io

 

<Content.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
import React, { Component } from "react";
import { tsConstructorType } from "@babel/types";
class Content extends Component {
  constructor(props) {
    super(props);
    
  }
  changePage(e){
    e.preventDefault();
    this.props.onClicked(e.target.dataset.id);
    
  }
  render() {
    var list = [];
    var data=this.props.contents;
    var i=0;
    while(i<data.length){
      var li=<li><a href='#' data-id={data[i].id} onClick={this.changePage.bind(this)}>{data[i].title}</a></li>
      list.push(li);
      ++i;
    }
    return (
      <nav>
        <ul>{list}</ul>
      </nav>
    );
  }
}
 
export default Content;
 
cs

자식 컴포넌트에서는 a태그를 쫙 깔아주는데

onClick=핸들링함수 일케 해주면 이벤트가 알아서 해당 함수의 인자로 전달된다.

changePage함수가 실행되고 이 때도 마찬가지로 바인딩을 해줘야 changePage 내부의 this키워드를 제대로 사용할 수 있다.

 

e.preventDefault()로 a태그가 기본적으로 수행하는 이벤트처리를 막아주고

this.props.onClicked()를 호출한다. 즉 App컴포넌트에서 넘어온 핸들링 함수를 수행한다.

html5부터 추가됐다던가 뭐던가 하튼간 태그에 data-로 시작하는 속성을 달아주면

dataset안에 속성명으로 속성들이 생긴다.

data-id={} 이런식으로 id값들을 세팅해줬기 때문에 이제 a태그의 dataset속성 안에 id값들이 배정된다.

e.target으로 이벤트가 발생된 a태그를 찾아내고 dataset에 id를 찾아내서

App컴포넌트에서 props로 넘어온 함수에 인자로 넘긴다.

 

그럼 App컴포넌트에선 클릭된 놈의 내용을 맨 밑에 띄워준다.

onClicked말고도 값이 변경될때마다 냄새를 맡는 onChange도 있고

form에서는 onSubmit 쓰면된다.

 

<UpdateForm.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
import React, { Component } from "react";
class UpdateForm extends Component {
  constructor(props) {
    super(props);
    this.state = {
      id: props.data.id,
      title: props.data.title,
      desc: props.data.desc
      
    };
    this.changeHandler=this.changeHandler.bind(this);
  }
  changeHandler(e){
      this.setState({[e.target.name]:e.target.value});
      //javascript 신종문법!
      //if e.target.name==='title'이면 title:바꿔야하고 이런거 대신에 []로 처리해주면땡
  }
  render() {
    return (
      <div>
        <form
          action="#"
          method="post"
          onSubmit={function(e) {
            e.preventDefault();
 
            var title = e.target.title.value;
            var desc = e.target.desc.value;
            this.props.updateContent(this.props.data.id, title, desc);
          }.bind(this)}
        >
          <input
            name="title"
            value={this.state.title}
            placeholder="title"
            onChange={this.changeHandler}
          ></input>
          <input
            name="desc"
            value={this.state.desc}
            placeholder="desc"
            onChange={this.changeHandler}
          ></input>
          <input type="submit"></input>
        </form>
      </div>
    );
  }
}
 
export default UpdateForm;
//그냥 input으로 놓으면 값이 변경이안된다
/* 따라서 자신의 state에 title,desc를 세팅해놓고 input에서 이벤트가 발생할때마다 (onChange=)
state의 title,desc가 바뀌게끔 해줘야한다. 그러면 자동으로 input의 value도 바뀐값을 참조하게되므로 input에 있는 값이 바뀐다.
이때 굳이 props로 넘어온걸 state에 할당해서 바꿔주는이유는, props는 R/O이기 때문이다.
*/
 
cs

내용을 업데이트 해주는 form이다.

' > 리액트' 카테고리의 다른 글

[리액트]형상관리  (0) 2019.08.31
[리액트]앱 빌드/배포  (0) 2019.08.31
[리액트]props state  (0) 2019.08.31
[리액트]컴포넌트  (0) 2019.08.31
[리액트]플젝 만들기  (0) 2019.08.31

+ Recent posts