티스토리 뷰

 이번 시간부터는 지난 시간까지 배웠던 React의 문법을 사용하여 간단한 가계부를 만들어 보도록 하겠습니다. 여러 게시글을 통해 점차 살을 붙여갈 것입니다.


프로젝트 설치 및 시작


 우선 새로운 프로젝트를 하나 설치하고 그 곳에서 작업하도록 하겠습니다. VS Code를 실행하고 개발 서버를 시작해주세요


1
2
3
4
5
create-react-app account-book-example
 
cd account-book-example

yarn start
cs


 시작하겠습니다. 우선 프로젝트의 src 안에 components 디렉터리를 생성해주세요. 이제부터 생성할 컴포넌트는 이 곳에 넣도록 하겠습니다.


컴포넌트 추가 - AccountBookForm


 src/components/AccountBookForm.js 파일을 생성해 주세요. 사용자가 이 컴포넌트를 통해 가계부에 기입을 합니다. 이 곳에서 input 태그의 값을 state에 담는 법을 알려드리겠습니다.


 components/AccountBookForm.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
// components/AccountBookForm.js
import React, { Component } from "react";
 
// 현재시간을 특정 format의 문자열로 반환
const getCurrentTimetoString = () => {
  return new Date().toLocaleString();
};
 
class AccountBookForm extends Component {
  state = {
    type: "지출",
    price: "",
    usage: "",
    date: ""
  };
 
  // input 태그의 내용에 변화가 발생했을 때 이벤트 처리
  changeInput = event => {
    this.setState({
      [event.target.name]: event.target.value,
      date: getCurrentTimetoString()
    });
  };
 
  render() {
    return (
      <form>
        <select name="type" onChange={this.changeInput}>
          <option defaultValue>지출</option>
          <option>수입</option>
        </select>
        <input
          placeholder="금액"
          type="number"
          name="price"
          value={this.state.price}
          onChange={this.changeInput}
        />
        <input
          placeholder="사용목적"
          name="usage"
          value={this.state.usage}
          onChange={this.changeInput}
        />
        <div>
          <span>타입 : {this.state.type}</span>
          <br />
          <span>
            금액 : {this.state.price !== "" ? `${this.state.price}원` : "0원"}
          </span>
          <br />
          <span>용도 : {this.state.usage !== "" ? this.state.usage : "-"}</span>
          <br />
          <span>날짜 : {this.state.date}</span>
          <br />
        </div>
      </form>
    );
  }
}
 
export default AccountBookForm;
cs


 다음은 App.js 파일을 수정합니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
// App.js
import React, { Component } from "react";
import "./App.css";
 
import AccountBookForm from "./components/AccountBookForm";
 
class App extends Component {
  render() {
    return <AccountBookForm />;
  }
}
 
export default App;
cs


 결과는?



 다음과 같이 select, input 박스의 내용을 바꿀 때마다 아래의 내용이 갱신되는 것을 확인할 수 있습니다. form 태그 내에 input 태그나 select 태그가 하나 있다면 changeInput 함수에서 setState를 사용할 때 키를 직접 적어두어도 되지만 여러 입력 태그들이 같은 onChange 이벤트를 받게 하려면 [event.target.name]을 이용해서 입력 태그의 name과 state의 키를 맞춰주면 됩니다. 이것은 javascript의 Computed property names라는 문법입니다. 이렇게 하지 않으려고 한다면 입력 태그마다 onChange용 함수를 여러개 만들면 같은 효과를 얻을 수 있습니다.


 이번에는 부모 component에 있는 함수를 자식 component에서 호출하는 법에 대해 알려드리겠습니다. 방법은 간단합니다. 부모 component에서 자식 component를 생성할 때 props로 호출하고자 하는 함수를 전달하면 됩니다. 자식 component에서 특정 이벤트가 발생했을 때, 부모 component의 state 값이 변경되거나 갱신되는 로직에서 이 방법을 사용합니다.


 components/AccountBookForm.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
// components/AccountBookForm.js
import React, { Component } from "react";
 
// 현재시간을 특정 format의 문자열로 반환
const getCurrentTimetoString = () => {
  return new Date().toLocaleString();
};
 
class AccountBookForm extends Component {
  // error 방지를 위한 기본 값 설정
  static defaultProps = {
    onAdd: () => {
      console.log("onAdd is not defined.");
    }
  };
 
  state = {
    type: "지출",
    price: "",
    usage: "",
    date: ""
  };
 
  // input 태그의 내용에 변화가 발생했을 때 이벤트 처리
  changeInput = event => {
    this.setState({
      [event.target.name]: event.target.value,
      date: getCurrentTimetoString()
    });
  };
 
  // form 태그의 submit 이벤트 처리
  submit = event => {
    // form의 submit의 효과로 발생하는 페이지 리로딩 방지
    // 페이지 리로딩이 발생하면 state값이 초기화됨
    event.preventDefault();
    // 부모 component로부터 받은 add를 실행
    this.props.onAdd(this.state);
    // 컴포넌트의 state를 기본값으로 초기화
    this.setState({
      type: "지출",
      price: "",
      usage: "",
      date: ""
    });
  };
 
  render() {
    return (
      <form onSubmit={this.submit}>
        <select name="type" onChange={this.changeInput}>
          <option defaultValue>지출</option>
          <option>수입</option>
        </select>
        <input
          placeholder="금액"
          type="number"
          name="price"
          value={this.state.price}
          onChange={this.changeInput}
        />
        <input
          placeholder="사용목적"
          name="usage"
          value={this.state.usage}
          onChange={this.changeInput}
        />
        <button type="submit">추가</button>
      </form>
    );
  }
}
 
export default AccountBookForm;
cs


 App.js 파일을 수정합니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// App.js
import React, { Component } from "react";
import "./App.css";
 
import AccountBookForm from "./components/AccountBookForm";
 
class App extends Component {
  add = data => {
    console.log(data);
  };
 
  render() {
    return <AccountBookForm onAdd={this.add} />;
  }
}
 
export default App;
cs


 결과는?



 자식 component(AccountBookForm)의 내용을 입력 후 추가 버튼을 누르면 부모 component(App)의 add함수를 호출해서 다음과 같이 개발자 console에 값이 전달되는 것을 확인할 수 있습니다. 


References


[Velopert 블로그 input상태 관리하기] https://velopert.com/3634



'프로그래밍 > React' 카테고리의 다른 글

[예제]간단한 가계부3 - 배열관련 처리2  (0) 2019.02.10
[예제]간단한 가계부2 - 배열관련 처리1  (0) 2019.02.08
[문법]Life Cycle API  (0) 2019.02.04
[문법]props와 state  (0) 2019.01.31
[문법]JSX  (0) 2019.01.29
댓글