[React Native] Redux로 Counter 앱 만들기

in #kr5 years ago (edited)

ReduxNativeBase 를 사용하여 카운터 앱을 만들어 봅니다. NativeBase를 사용하니 컴포넌트 UI가 좀더 수려해졌습니다. 그리고 복잡한 앱을 구현할 때에는 Redux가 필수입니다.

리덕스(Redux)를 사용하지 않을 때와 사용할 때의 차이점은 아래 그림이 잘 표현하고 있습니다.



필요한 모듈 설치하기

expo-cli가 설치되어 있지 않으면 아래와 같이 설치한다.

$ npm install expo-cli --global


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

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


그리고 Reduxreact-redux를 설치한다.

$ npm install redux react-redux --save


마지막으로 NativeBase를 설치한다.

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



구현하기

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

Redux Reducers 구현

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

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

reducers/countReducer.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;

INCREMENTDECREMENT 액션은 카운트 값을 계산하여 반환한다.

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

reducers/index.js

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

const allReducers = combineReducers({
  countReducer,
});

export default allReducers;


Redux 컴포넌트 구현

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

components/counter.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);


Redux Store 구현

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

App.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>
    );
  }
}



실행하기

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

$ npm start



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



같이 읽으면 좋은 글:


Sponsored ( Powered by dclick )
DCLICK: An Incentivized Ad platform by Proof of Click - 스팀 기반 애드센스를 소개합니다.

안녕하세요 스티미언 여러분. 오늘 여러분께 스팀 블록체인 기반 광고 플랫폼 DCLICK을 소개...

Sort:  

짱짱맨 호출에 응답하여 보팅하였습니다.

감사합니다.

Congratulations @anpigon! You have completed the following achievement on the Steem blockchain and have been rewarded with new badge(s) :

You received more than 4000 upvotes. Your next target is to reach 5000 upvotes.

Click here to view your Board
If you no longer want to receive notifications, reply to this comment with the word STOP

Do not miss the last post from @steemitboard:

SteemWhales has officially moved to SteemitBoard Ranking
SteemitBoard - Witness Update

Support SteemitBoard's project! Vote for its witness and get one more award!

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

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

상세한 개발 내용 고맙습니다~
저도 다시 웹 프로그래밍 좀 해봐야겠어요~ ㅎ

저는 요즘 리액트 네이티브로 모바일앱 개발에 푹 빠져있어요.
최근에는 바빠서 못하고 있네요.
빨리 공부해서 모바일앱을 만들어 보고 싶어요. ㅋㅋ

Coin Marketplace

STEEM 0.29
TRX 0.12
JST 0.033
BTC 63464.16
ETH 3111.33
USDT 1.00
SBD 3.98