react-nativeで作るiOSアプリ 第7回 一番簡単なreduxアプリを作る

こんにちは!個別指導塾コミット塾長、AWESOME開発担当の船津です。

今回はreduxでカウンターアプリを作ってみましょう。
どんなアプリを作るかも決まっていないのに、最近流行っていると聞いて飛びついてみました。

目標は最小限の学習コストでredux react-nativeを使ってみることです。

参考にしたサイト

めちゃくちゃ簡単に書いてくださっているのでとても参考になりました。
少しわかってきたらこちらを参考にすると良いでしょう。

 

まずはアプリを新規作成しましょう。

react-native init PlaygroundApp

npm install --save react-redux redux

出来上がったpackage.jsonがこちら

{
  "name": "PlaygroundApp",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "start": "react-native start"
  },
  "dependencies": {
    "react": "15.2.1",
    "react-native": "0.29.0",
    "react-native-button": "^1.6.0",
    "react-redux": "^4.4.5",
    "redux": "^3.5.2",
  },
  "devDependencies": {}
}

index.ios.js いつも通りアプリの登録だけ行います。

'use strict';

import React, { AppRegistry} from 'react-native';
import App from './app/containers/app';

AppRegistry.registerComponent('PlaygroundApp', () => App);

components/app.js 親コンポーネントです。

stateを管理するstoreを作成して、カウンターをインポートします。
ConuterをちゃんとProviderで囲ってstore={store}としておかないとConnectでreduxとreact-nativeを連携するところで詰まります。
ここでは簡単のためにdispatchで使用するtypeを直接指定しています。

import React, { Component } from 'react';
import {
  StyleSheet,
  View,
  Text,
  TouchableOpacity,
 } from 'react-native';

import counter from '../reducers/index';
import Counter from './Counter';
import { createStore } from 'redux';
import { Provider } from 'react-redux';

const store = createStore(counter);

export default class App extends Component {
  render() {
    const { counter, count } = this.props;
    return (
      <Provider store={store}>
     {<Counter      increment={() => store.dispatch({ type :'INCREMENT' })}
      decrement={() => store.dispatch({ type :'DECREMENT' })}
      />}
    </Provider>
    );
  }
}

components/Counter.js 子コンポーネントを定義します。

storeがもっている値をreactで使用するために、connectメソッドを使います。
store.getState().countなどとしても値を持ってこれますが、そのままだとstateが変更されても画面は更新されません。
connect関数の置き場所で一番ハマりました。
今回のプロジェクトではここに書いていないと動きませんでした。

import React, { Component } from 'react';
import {
  StyleSheet,
  View,
  Text,
  TouchableOpacity,
 } from 'react-native';

import { connect } from 'react-redux';

export default class Counter extends Component {
  constructor(props) {
    super(props);
  }

  render() {
    const { count, increment, decrement } = this.props;
    return (
      <View style={styles.main}>
     <Text style={styles.counter}>
      Counter: {count}
     </Text>
     <TouchableOpacity onPress={increment} style={styles.button}>
     <Text style={styles.counter}>
      +
     </Text>
     </TouchableOpacity>
     <TouchableOpacity onPress={decrement} style={styles.button}>
     <Text style={styles.counter}>
     -
     </Text>
    </TouchableOpacity>
   </View>
    );
  }
}

function mapStateToProps(state) {
  return { count: state.count }
}
function mapDispatchToProps(dispatch) {
  return {
  };
}
export default connect(
  mapStateToProps
)(Counter);


const styles = StyleSheet.create({
  main: {
    flex: 1,
    flexDirection: 'column',
    justifyContent: 'center',
    alignItems: 'center',
  },
  counter: {
    fontSize: 16,
  },
  button: {
   width: 100,
   height: 30,
   padding: 10,
   backgroundColor: 'lightgray',
   alignItems: 'center',
   justifyContent: 'center',
   margin: 3
  }

});

reducers/index.js 実際のstateの変更を管理するところですね。

const initialState = {
  count: 0
};

export default function counter(state = initialState, action = {}){
  switch(action.type){
    case 'INCREMENT':
    console.log(state.count);
    return {
      count: state.count + 1
    }
    case 'DECREMENT':
    return {
      count: state.count - 1
    }
    default:
      return state;
  }
}

普段jsはjqueryくらいしか触らないので、reduxをやろうと思ってから実際に書いてみるまでかなりのハードルがありました。
触ってみるとかなり面白いかったです。
reduxを作る際はreactプロジェクトの中でも特に親子関係を意識して設計しないといけない一方、作ってしまえば管理は楽です。外国語の資料ばかりですが、みなさんも是非どうぞ。

PR

Instagram Feed

Load More
Something is wrong. Response takes too long or there is JS error. Press Ctrl+Shift+J or Cmd+Shift+J on a Mac.

Instagram

専務取締役

funatsukeisuke

WEBと教育を組み合わせて何かおもしろいことをやってやろうと画策しています。AWESOMEでは開発を担当、個別指導塾コミットでは塾長と2足の草鞋を履きながら日々勉強しています。

他の投稿を見る →