함께 성장하는 프로독학러

8-1. Counter 어플리케이션 만들기 - 1) 구상, action 본문

Programming/react.js

8-1. Counter 어플리케이션 만들기 - 1) 구상, action

프로독학러 2018. 4. 26. 22:03

안녕하세요, 프로독학러입니다.


이번 포스팅에서는 저번 포스팅에서 알아본 Redux 를 이용해 Counter 어플리케이션을 만들어보도록 하겠습니다.


*velopert 님의 Youtube 강의를 정리한 내용이라고 보시면 될 것 같습니다. (5강)

<Contact application - velopert>


먼저 우리가 만들 어플리케이션의 모습을 보고 어떻게 만들어야 할 지 구상해 보도록 하겠습니다.



간단한 모양새를 하고 있습니다.

가장 윗 부분에 숫자가 나와 있습니다.

그리고 아래의 +버튼을 누르면 숫자가 1씩 증가하고, -버튼을 누르면 1씩 감소합니다.

그리고 Randomize Color 버튼을 누르면 배경색이 랜덤하게 바뀝니다.



위의 그림처럼 말이죠.


그럼 만들어야 할 컴포넌트를 구성해 보도록 합시다.



가장 큰 컴포넌트는 모든 컴포넌트를 렌더링하는 Counter 컴포넌트입니다.

숫자가 표시되는 부분은 Value 컴포넌트입니다.

버튼 부분은 Control 컴포넌트로 만들도록 하겠습니다.


snippets 기능을 활용하여 세 컴포넌트를 빠르게 만들어보겠습니다.


(./src/components/Counter.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 PropTypes from 'prop-types';
 
const propTypes = {
};
const defaultProps = {
};
 
class Counter extends Component {
    state = {
 
    }
    render() {
        return (
            <div>
                <Value />
                <Control />
            </div>
        );
    }
}
 
Value.propTypes = propTypes;
Value.defaultProps = defaultProps;
 
export default Counter;
cs


(./src/components/Value.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
import React, { Component } from 'react';
import PropTypes from 'prop-types';
 
const propTypes = {
 
};
const defaultProps = {
 
};
 
class Value extends Component {
    state = {
 
    }
    render() {
        return (
            <div>
              <h1></h1>
            </div>
        );
    }
}
 
Value.propTypes = propTypes;
Value.defaultProps = defaultProps;
 
export default Value;
cs


(./src/components/Control.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
import React, { Component } from 'react';
import PropTypes from 'prop-types';
 
const propTypes = {
 
};
 
const defaultProps = {
 
};
 
class Control extends Component {
    state = {
 
    }
    render() {
        return (
            <div>
              <button>+</button>
              <button>-</button>
              <button>Randomize Color</button>
            </div>
        );
    }
}
 
Control.propTypes = propTypes;
Control.defaultProps = defaultProps;
 
export default Control;
cs


전화번호부 어플리케이션을 만들때와 달리 Redux 를 이용해 상태관리를 할 예정이므로 Counter 컴포넌트의 state 를 이용할 필요는 없습니다.

이전 포스팅에서도 언급한 바와 같이, Redux 를 이용하는 순서는 아래와 같습니다.


1. 액션 타입 생성 (action 은 객체이며, type 속성을 반드시 가지고 있어야 한다.)

2. 액션 생성 함수 정의 (액션 생성 함수를 통하여 action 객체를 빠르게 만들 수 있도록 도와줌)

3. 실질적으로 변화를 일으키는 함수인 리듀서 정의 (인자로는 prevState와 action이 들어옴, 들어오는 action 객체의 타입에 따라 어떤 변화를 일으킬지 정의)

4. 스토어 생성 (3에서 만든 리듀서를 포함하여 createStore를 통해 생성)

5. 스토어의 변화가 생길때 실행될 리스너 함수 정의

6. 클릭 등 이벤트에 dispatch 를 통해 액션 전달


위의 순서에 입각해 어플리케이션을 만들어 보도록 하겠습니다.



가장 먼저 할 일은 action 에 관련된 작업입니다.

action 은 작업에 대한 정보를 가지고 있는 '객체' 입니다.

액션객체는 디스패치로 스토어에게 보내져 리듀서가 액션객체에 따른 작업을 수행합니다.


우리가 만들 Counter 어플리케이션에서 수행되야할 작업은 총 세 개 입니다.

+ 버튼을 누르면 number 를 1 올리는 Increment 작업, 

- 버튼을 누르면 number 를 1 감소시키는 Decrement 작업, 

Randomize Color 버튼을 누르면 배경의 색깔이 바뀌는 Set_color 작업.

따라서 action 객체도 세 개가 필요하겠죠.


action에 관련된 파일들을 위한 폴더 'actions' 를 src 폴더 하위에 만들어 줍니다.


1) ActionTypes.js

action 객체는 type 속성을 필수속성으로 가지고 있어야 합니다. 

(액션객체의 type 속성에 따라 리듀서가 다르게 동작.)

각각 action 객체를 위한 type 을 지정하는 파일인 ActionTypes.js 파일을 생성합니다.

코드의 내용은 다음과 같습니다


(./src/actions/ActionTypes.js)

1
2
3
4
 export const INCREMENT = "INCREMENT";
 export const DECREMENT = "DECREMENT";
 export const SET_COLOR = "SET_COLOR";
 
cs


위의 코드에서 export 를 세 개 했는데, 이렇게 export 를 여러 개 하게 되면, 불러오는(import) 방법은 두 가지 입니다.

첫 번째는 중괄호 안에 export 된 변수나 상수의 이름을 불러오는 방법입니다.


(export 를 여러 번 한 파일을 불러올 때 1)

1
import { INCREMENT } from './ActionTypes';
cs


위의 코드와 같이 말이죠.


두 번째 방법은 * as 임포트될 파일내에서 사용할 변수명 을 이용하는 방법입니다.


(export 를 여러 번 한 파일을 불러올 때 2)

1
import * as types from './ActionTypes';
cs


위의 * as 방식을 이용하면 객체처럼 사용가능합니다.

위의 코드와 같이 임포트하면 types.INCREMENT 로 "INCREMENT" 를 사용할 수 있습니다.


2) index.js


actions 폴더 하위에 index.js 파일을 만들어줍니다.

*어떤 폴더의 index 파일을 만든다는 것은 해당 폴더의 디폴트 임포트 값을 의미합니다.

(actions 폴더에 index.js 파일을 만들고 actions 폴더를 임포트하면 자동으로 index.js 파일이 임포트된다.)


이 파일은 액션생성자 파일입니다.

action 은 '객체' 입니다. 그리고 필수 속성으로 type 을 가지고 있습니다.

type 이외의 다른 속성들은 용도에 따라 정의 하면 됩니다.

하지만 매번  action 객체를 직접만든다면 코드의 효율성이 떨어집니다.

따라서 액션의 모양(객체)을 만들어 주는 함수를 정의해 그 함수의 실행으로 액션객체를 만드는 것입니다.

코드의 내용은 다음과 같습니다. 


(./src/actions/index.js)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import * as types from './ActionTypes';
 
export function increment() {
  return {
    type : types.INCREMENT
  };
}
 
export function decrement() {
  return {
    type : types.DECREMENT
  };
}
 
export function setColor(color) {
  return {
    type : types.SET_COLOR,
    color
  };
}
cs


코드의 첫 번째 줄에서 1)에서 만든 액션타입들을 types 객체로 호출했습니다.

그리고 3, 9, 15 번째 줄에서 각각 increment, decrement, setColor 함수를 정의 했습니다.

각각의 함수는 액션 객체를 리턴합니다. (액션생성자)

마지막 액션생성자인 setColor 는 파라메터로 color 값이 들어오고, color 키의 값으로 들어오는 인자를 취합니다.

(ES6 의 property shorthand 문법입니다. 이에 익숙하지 않으신 분들은 아래의 링크를 참조해 주세요.)

<ES6 - property shorthand>


여기까지 action 에 관련된 작업을 완료했습니다.


1. 액션 타입 생성 (action 은 객체이며, type 속성을 반드시 가지고 있어야 한다.)

2. 액션 생성 함수 정의 (액션 생성 함수를 통하여 action 객체를 빠르게 만들 수 있도록 도와줌)

3. 실질적으로 변화를 일으키는 함수인 리듀서 정의 (인자로는 prevState와 action이 들어옴, 들어오는 action 객체의 타입에 따라 어떤 변화를 일으킬지 정의)

4. 스토어 생성 (3에서 만든 리듀서를 포함하여 createStore를 통해 생성)

5. 스토어의 변화가 생길때 실행될 리스너 함수 정의

6. 클릭 등 이벤트에 dispatch 를 통해 액션 전달


위의 순서의 2번 까지 완료한 상태입니다.

다음 포스팅에서 3, 4, 5, 6번을 진행하도록 하겠습니다.

감사합니다.


**참고 자료 (항상 감사드립니다)

https://velopert.com/reactjs-tutorials


*다녀가셨다는 표시는 공감으로 부탁드릴게요! (로그인 하지 않으셔도 공감은 가능합니다 ㅎㅎ)

Comments