[React Native] Redux로 Counter 앱 만들기 by anpigon

View this thread on steempeak.com
· @anpigon · (edited)
$2.37
[React Native] Redux로 Counter 앱 만들기
![](https://cdn.steemitimages.com/p/9vWp6aU4y8kwSZ9GrA6TWcxjsEnJX399aXrr8f5QWawsEAFBDLtXCm1DRywaBMM2GAzKPK4BCw7mwWwMQNn8fq1MJH6oVYmTio2ynn3L1oHHv1ZnF4FG6kg53xFXhAiTZ6ozT2XGYYH6sikF8?format=match&mode=fit)

[Redux](https://github.com/reactjs/react-redux) 와 [NativeBase](https://nativebase.io/) 를 사용하여 카운터 앱을 만들어 봅니다. **NativeBase**를 사용하니 컴포넌트 UI가 좀더 수려해졌습니다. 그리고 복잡한 앱을 구현할 때에는 Redux가 필수입니다.

리덕스(Redux)를 사용하지 않을 때와 사용할 때의 차이점은 아래 그림이 잘 표현하고 있습니다.
![](https://cdn.steemitimages.com/p/62PdCoV9UZqKxEeNM1pVMLWxNVQ2bXSbEJE5Zsy5GRmfJJVqkTDFJabcyNcoJjSTQXqPYqvSRGX4whxtqtbFvfJ8f1Q3bdF4iJXKfh4uidSqL54?format=match&mode=fit)

<br><br>

# 필요한 모듈 설치하기

[expo-cli](https://docs.expo.io/versions/latest/workflow/expo-cli)가 설치되어 있지 않으면 아래와 같이 설치한다.

```bash
$ npm install expo-cli --global
```

<br>**expo-cli**를 사용하여 프로젝트를 생성한다.

```bash
$ expo init redux-counter-app
$ cd redux-counter-app
```

<br>그리고 **Redux**와 **react-redux**를 설치한다.

```bash
$ npm install redux react-redux --save
```

<br>마지막으로 **NativeBase**를 설치한다.

```bash
$ npm install native-base --save
$ npm install @expo/vector-icons --save
```

<br><br>

# 구현하기

프로젝트의 루트에 세 개의 폴더 `reducers, components` 를 생성한다.

### Redux Reducers 구현

Reducers는 앱에서 필요한 데이터를 반환한다. 여기서는 `Counter` 값을 반환하는 reducer가 필요하다. `reducers` 폴더에 `countReducer.js` 파일을 생성한다. 

다음과 같이 하나의 `js` 파일에 액션과 리듀서를 모두 구현하는 것을 **Ducks 구조**이라고 한다. Ducks 구조를 사용하면 나중에 코드 관리하기가 편하다.

**reducers/countReducer.js** 

```js
// Default State
const initialState = {
	count: 0
};

// Actions
export const INCREMENT = "Increment";
export const DECREMENT = "Decrement";

// Action Functions
export function increment(){
  return {
    type: INCREMENT
  };
}
export function decrement(){
  return {
    type: DECREMENT
  };
}

// Reducer
function reducer(state = initialState, action) {
  switch (action.type) {
    case INCREMENT: 
      return {
        count: state.count + 1
      }
    case DECREMENT: 
      return {
        count: state.count - 1
      }
  }
  return state;
}

// Exports Default
export default reducer;
```
`INCREMENT `과 `DECREMENT ` 액션은 카운트 값을 계산하여 반환한다. 

그 다음은 `index.js` 파일에서 모든 Reducer를 결합한다. 지금은 하나의 리듀서 `countReducer`만 있지만, 나중에 리듀서가 여러 개일 경우 유용하다.

**reducers/index.js**

```js
import { combineReducers } from 'redux';
import countReducer from './countReducer.js';

const allReducers = combineReducers({
  countReducer,
});

export default allReducers;
```

<br>

### Redux 컴포넌트 구현

이제 `<Counter>` 컴포넌트를 구현한다. 

**components/counter.js** 

```js
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { Container, Content, Text, Card, Header, Body, Button, Title, CardItem } from 'native-base';
import { increment, decrement } from '../reducers/countReducer';

class Counter extends Component {
	render() {
    return(
      <Container>
        <Header>
          <Body>
            <Title>Redux Counter</Title>
          </Body>
        </Header>
        <Content padder>
          <Card>
            <CardItem>
              <Text>
                { this.props.state.count }
              </Text>
            </CardItem>
          </Card>
          <Button full onPress= {() => this.props.increment()} style={{marginVertical: 10}}>
            <Text>Increment</Text>
          </Button>
          <Button full dark bordered onPress= {() => this.props.decrement()}>
            <Text>Decrement</Text>
          </Button>
        </Content>
      </Container>
    );
  }
}

// Reducer 데이터를 props로 변환
function mapStateToProps(state){
  return {
    state: state.countReducer
  };
}

// Actions을 props로 변환
function matchDispatchToProps(dispatch){
  return bindActionCreators({
    increment: increment,
    decrement: decrement
  }, dispatch);
}

export default connect(mapStateToProps, matchDispatchToProps)(Counter);
```

<br>

### Redux Store 구현

마지막으로 `App.js` 파일에 store를 만들어야 한다. Redux에 대한 기본 개념은 [Redux 공식 문서](http://redux.js.org/)를 참고한다. `App.js` 파일을 아래와 같이 수정한다.

**App.js** 

```js
import React, { Component } from 'react';
import { Provider } from 'react-redux';
import { createStore } from 'redux';
import allReducers from './reducers';
import Counter from './components/counter.js';

const store = createStore(allReducers);

export default class App extends Component{
  render(){
    return(
      <Provider store={store}>
        <Counter />
      </Provider>
    );
  }
}
```

 <br><br>

# 실행하기

앱을 실행하고 확인해보자.

```bash
$ npm start
```

<br>

![](https://user-images.githubusercontent.com/3969643/51070641-f945ad80-1687-11e9-92ef-30895ec9359e.gif)

<br>

여기까지 읽어주셔서 감사합니다.

<br>

___ 

**같이 읽으면 좋은 글:**
* [리덕스(Redux)를 왜 쓸까? 그리고 리덕스를 편하게 사용하기 위한 발악 (i)](https://velopert.com/3528)
* [리덕스(Redux)를 왜 쓸까? 그리고 리덕스를 편하게 사용하기 위한 발악 (ii)](https://velopert.com/3533)

---

#####  <sub> **Sponsored ( Powered by [dclick](https://www.dclick.io) )** </sub>
##### [DCLICK: An Incentivized Ad platform by Proof of Click - 스팀 기반 애드센스를 소개합니다.](https://api.dclick.io/v1/c?x=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjIjoiYW5waWdvbiIsInMiOiJyZWFjdC1uYXRpdmUtcmVkdXgtY291bnRlci0tMTU0NzI3ODIzNTA0OCIsImEiOlsidC0xIl0sInVybCI6Imh0dHBzOi8vc3RlZW1pdC5jb20vZGNsaWNrL0BkY2xpY2svZGNsaWNrLWFuLWluY2VudGl2aXplZC1hZC1wbGF0Zm9ybS1ieS1wcm9vZi1vZi1jbGljay0iLCJpYXQiOjE1NDcyNzgyMzUsImV4cCI6MTg2MjYzODIzNX0.Ke2puEP3Ed5ygIDTapqiEgpKZzjfe-89xyA78Dkwn9s)
<sup>안녕하세요 스티미언 여러분. 오늘 여러분께 스팀 블록체인 기반 광고 플랫폼 DCLICK을 소개...</sup>
</center>
👍  , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , and 147 others
👎  
properties (23)
post_id68,711,688
authoranpigon
permlinkreact-native-redux-counter--1547278235048
categorykr
json_metadata{"tags":["kr","kr-dev","react","busy","jjangjjangman"],"app":"busy\/2.5.6","format":"markdown","community":"busy","users":["expo"],"links":["https:\/\/github.com\/reactjs\/react-redux","https:\/\/nativebase.io\/","https:\/\/docs.expo.io\/versions\/latest\/workflow\/expo-cli","http:\/\/redux.js.org\/","https:\/\/velopert.com\/3528","https:\/\/velopert.com\/3533","https:\/\/www.dclick.io","https:\/\/api.dclick.io\/v1\/c?x=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjIjoiYW5waWdvbiIsInMiOiJyZWFjdC1uYXRpdmUtcmVkdXgtY291bnRlci0tMTU0NzI3ODIzNTA0OCIsImEiOlsidC0xIl0sInVybCI6Imh0dHBzOi8vc3RlZW1pdC5jb20vZGNsaWNrL0BkY2xpY2svZGNsaWNrLWFuLWluY2VudGl2aXplZC1hZC1wbGF0Zm9ybS1ieS1wcm9vZi1vZi1jbGljay0iLCJpYXQiOjE1NDcyNzgyMzUsImV4cCI6MTg2MjYzODIzNX0.Ke2puEP3Ed5ygIDTapqiEgpKZzjfe-89xyA78Dkwn9s"],"image":["https:\/\/cdn.steemitimages.com\/p\/9vWp6aU4y8kwSZ9GrA6TWcxjsEnJX399aXrr8f5QWawsEAFBDLtXCm1DRywaBMM2GAzKPK4BCw7mwWwMQNn8fq1MJH6oVYmTio2ynn3L1oHHv1ZnF4FG6kg53xFXhAiTZ6ozT2XGYYH6sikF8?format=match&mode=fit"]}
created2019-01-12 07:30:36
last_update2019-01-12 07:35:21
depth0
children8
net_rshares4,718,217,552,473
last_payout2019-01-19 07:30:36
cashout_time1969-12-31 23:59:59
total_payout_value1.832 SBD
curator_payout_value0.539 SBD
pending_payout_value0.000 SBD
promoted0.000 SBD
body_length5,416
author_reputation105,789,957,935,122
root_title"[React Native] Redux로 Counter 앱 만들기"
beneficiaries[]
max_accepted_payout1,000,000.000 SBD
percent_steem_dollars10,000
author_curate_reward""
vote details (212)
@bukio ·
짱짱맨 호출에 응답하여 보팅하였습니다.
properties (22)
post_id68,712,087
authorbukio
permlinkre-bukio-jjangjjangman-1547279166246
categorykr
json_metadata{"tags":["bukio","jjangjjangman"],"app":"steemer\/1.0"}
created2019-01-12 07:46:06
last_update2019-01-12 07:46:06
depth1
children1
net_rshares0
last_payout2019-01-19 07:46:06
cashout_time1969-12-31 23:59:59
total_payout_value0.000 SBD
curator_payout_value0.000 SBD
pending_payout_value0.000 SBD
promoted0.000 SBD
body_length21
author_reputation12,334,203,545,676
root_title"[React Native] Redux로 Counter 앱 만들기"
beneficiaries[]
max_accepted_payout1,000,000.000 SBD
percent_steem_dollars10,000
@anpigon ·
감사합니다.
properties (22)
post_id68,713,595
authoranpigon
permlinkre-bukio-re-bukio-jjangjjangman-1547279166246-20190112t083954446z
categorykr
json_metadata{"community":"busy","app":"busy\/2.5.6","format":"markdown","tags":["kr"],"users":[],"links":[],"image":[]}
created2019-01-12 08:40:42
last_update2019-01-12 08:40:42
depth2
children0
net_rshares0
last_payout2019-01-19 08:40:42
cashout_time1969-12-31 23:59:59
total_payout_value0.000 SBD
curator_payout_value0.000 SBD
pending_payout_value0.000 SBD
promoted0.000 SBD
body_length6
author_reputation105,789,957,935,122
root_title"[React Native] Redux로 Counter 앱 만들기"
beneficiaries[]
max_accepted_payout1,000,000.000 SBD
percent_steem_dollars10,000
@gomdory ·
![](https://ipfs.busy.org/ipfs/QmSpSf3UTPCZUwCEfi1sWKKcUXWKH3SnpEaYaqRuWu7omz)
properties (22)
post_id68,716,872
authorgomdory
permlinkre-react-native-redux-counter--1547278235048-20190112t104801
categorykr
json_metadata{}
created2019-01-12 10:48:03
last_update2019-01-12 10:48:03
depth1
children0
net_rshares0
last_payout2019-01-19 10:48:03
cashout_time1969-12-31 23:59:59
total_payout_value0.000 SBD
curator_payout_value0.000 SBD
pending_payout_value0.000 SBD
promoted0.000 SBD
body_length78
author_reputation43,207,143,526,344
root_title"[React Native] Redux로 Counter 앱 만들기"
beneficiaries[]
max_accepted_payout1,000,000.000 SBD
percent_steem_dollars10,000
@steemitboard ·
Congratulations @anpigon! You have completed the following achievement on the Steem blockchain and have been rewarded with new badge(s) :

<table><tr><td>https://steemitimages.com/60x70/http://steemitboard.com/@anpigon/voted.png?201901121056</td><td>You received more than 4000 upvotes. Your next target is to reach 5000 upvotes.</td></tr>
</table>

<sub>_[Click here to view your Board](https://steemitboard.com/@anpigon)_</sub>
<sub>_If you no longer want to receive notifications, reply to this comment with the word_ `STOP`</sub>



**Do not miss the last post from @steemitboard:**
<table><tr><td><a href="https://steemit.com/steem/@steemitboard/steemwhales-has-officially-moved-to-steemitboard-ranking"><img src="https://steemitimages.com/64x128/https://cdn.steemitimages.com/DQmfRVpHQhLDhnjDtqck8GPv9NPvNKPfMsDaAFDE1D9Er2Z/header_ranking.png"></a></td><td><a href="https://steemit.com/steem/@steemitboard/steemwhales-has-officially-moved-to-steemitboard-ranking">SteemWhales has officially moved to SteemitBoard Ranking</a></td></tr><tr><td><a href="https://steemit.com/steemitboard/@steemitboard/steemitboard-witness-update-2019-01-07"><img src="https://steemitimages.com/64x128/http://i.cubeupload.com/7CiQEO.png"></a></td><td><a href="https://steemit.com/steemitboard/@steemitboard/steemitboard-witness-update-2019-01-07">SteemitBoard - Witness Update</a></td></tr></table>

> Support [SteemitBoard's project](https://steemit.com/@steemitboard)! **[Vote for its witness](https://v2.steemconnect.com/sign/account-witness-vote?witness=steemitboard&approve=1)** and **get one more award**!
properties (22)
post_id68,717,948
authorsteemitboard
permlinksteemitboard-notify-anpigon-20190112t112602000z
categorykr
json_metadata{"image":["https:\/\/steemitboard.com\/img\/notify.png"]}
created2019-01-12 11:26:00
last_update2019-01-12 11:26:00
depth1
children0
net_rshares0
last_payout2019-01-19 11:26:00
cashout_time1969-12-31 23:59:59
total_payout_value0.000 SBD
curator_payout_value0.000 SBD
pending_payout_value0.000 SBD
promoted0.000 SBD
body_length1,596
author_reputation38,705,954,145,809
root_title"[React Native] Redux로 Counter 앱 만들기"
beneficiaries[]
max_accepted_payout1,000,000.000 SBD
percent_steem_dollars10,000
@steem-ua ·
#### Hi @anpigon!

Your post was upvoted by @steem-ua, new Steem dApp, using UserAuthority for algorithmic post curation!
Your **UA** account score is currently 2.813 which ranks you at **#12416** across all Steem accounts.
Your rank has improved 41 places in the last three days (old rank 12457).

In our last Algorithmic Curation Round, consisting of 257 contributions, your post is ranked at **#163**.
##### Evaluation of your UA score:

* Only a few people are following you, try to convince more people with good work.
* The readers like your work!
* You have already shown user engagement, try to improve it further.


**Feel free to join our [@steem-ua Discord server](https://discord.gg/KpBNYGz)**
properties (22)
post_id68,736,998
authorsteem-ua
permlinkre-react-native-redux-counter--1547278235048-20190112t220137z
categorykr
json_metadata{"app":"beem\/0.20.14"}
created2019-01-12 22:01:39
last_update2019-01-12 22:01:39
depth1
children0
net_rshares0
last_payout2019-01-19 22:01:39
cashout_time1969-12-31 23:59:59
total_payout_value0.000 SBD
curator_payout_value0.000 SBD
pending_payout_value0.000 SBD
promoted0.000 SBD
body_length705
author_reputation23,203,609,903,979
root_title"[React Native] Redux로 Counter 앱 만들기"
beneficiaries[]
max_accepted_payout1,000,000.000 SBD
percent_steem_dollars10,000
@surpassinggoogle ·
Task Request. We Modified Our Task Request To Add Core Features & 'Communities' To Ulogs.org, Simplifying The 1.5 Task Drastically. + (500 Steem Is Completed In 7 days/550 Steem For 5 Days)


The task has been drastically simplified and the first task is partially done. Ulogs is front-end only and a fork of busy. It uses React JS. This tasks have been delayed. It has been more than a month already. Please consider helping me or please pass it on, to anyone who can help me. The time allotment for both tasks is 7 days.


https://steemit.com/utopian-io/@surpassinggoogle/task-request-we-modified-our-task-request-to-add-core-features-and-communities-to-ulogs-org-simplifying-the-1-5-task-drastically
properties (22)
post_id68,846,378
authorsurpassinggoogle
permlinkre-anpigon-react-native-redux-counter--1547278235048-20190115t160426087z
categorykr
json_metadata{"tags":["kr"],"links":["https:\/\/steemit.com\/utopian-io\/@surpassinggoogle\/task-request-we-modified-our-task-request-to-add-core-features-and-communities-to-ulogs-org-simplifying-the-1-5-task-drastically"],"app":"steemit\/0.1"}
created2019-01-15 16:04:30
last_update2019-01-15 16:04:30
depth1
children0
net_rshares0
last_payout2019-01-22 16:04:30
cashout_time1969-12-31 23:59:59
total_payout_value0.000 SBD
curator_payout_value0.000 SBD
pending_payout_value0.000 SBD
promoted0.000 SBD
body_length702
author_reputation508,940,095,151,809
root_title"[React Native] Redux로 Counter 앱 만들기"
beneficiaries[]
max_accepted_payout1,000,000.000 SBD
percent_steem_dollars10,000
@etainclub ·
상세한 개발 내용 고맙습니다~
저도 다시 웹 프로그래밍 좀 해봐야겠어요~ ㅎ
properties (22)
post_id69,026,458
authoretainclub
permlinkre-anpigon-react-native-redux-counter--1547278235048-20190119t141336370z
categorykr
json_metadata{"tags":["kr"],"app":"steemit\/0.1"}
created2019-01-19 14:13:36
last_update2019-01-19 14:13:36
depth1
children1
net_rshares0
last_payout2019-01-26 14:13:36
cashout_time1969-12-31 23:59:59
total_payout_value0.000 SBD
curator_payout_value0.000 SBD
pending_payout_value0.000 SBD
promoted0.000 SBD
body_length42
author_reputation784,231,792,440,997
root_title"[React Native] Redux로 Counter 앱 만들기"
beneficiaries[]
max_accepted_payout1,000,000.000 SBD
percent_steem_dollars10,000
@anpigon ·
저는 요즘 리액트 네이티브로 모바일앱 개발에 푹 빠져있어요. 
최근에는 바빠서 못하고 있네요.
빨리 공부해서 모바일앱을 만들어 보고 싶어요. ㅋㅋ
properties (22)
post_id69,028,474
authoranpigon
permlinkre-etainclub-re-anpigon-react-native-redux-counter--1547278235048-20190119t150116179z
categorykr
json_metadata{"community":"busy","app":"busy\/2.5.6","format":"markdown","tags":["kr"],"users":[],"links":[]}
created2019-01-19 15:01:21
last_update2019-01-19 15:01:21
depth2
children0
net_rshares0
last_payout2019-01-26 15:01:21
cashout_time1969-12-31 23:59:59
total_payout_value0.000 SBD
curator_payout_value0.000 SBD
pending_payout_value0.000 SBD
promoted0.000 SBD
body_length81
author_reputation105,789,957,935,122
root_title"[React Native] Redux로 Counter 앱 만들기"
beneficiaries[]
max_accepted_payout1,000,000.000 SBD
percent_steem_dollars10,000