LoginSignup
1
4

More than 3 years have passed since last update.

【React Native】アプリ開発を楽にする、ボイラープレート更新したよ (expo 最新: SDK 35)

Last updated at Posted at 2019-10-11

背景

一年前、こちらのボイラープレートをひっそりリリースしていました。当時はまだReact Native始めたばかりで、非効率でわかりづらいコードもありましたが、それから1年JSスタックでの開発を経験し改めてこのボイラープレートを改善しようと決意。

ボイラープレートとは

新しくReactNativeでアプリを作り始める時の、お決まりの構成。テンプレート的なものになります。本来、アプリ開発を始める時、プロジェクトのセットアップが必要になります。ファイル構造を変更し、必要なライブラリをインストールし、UIコンポーネントを作成する。これらにかかる時間は時に膨大で、特に初めてReact Nativeを触る人にとってはとても大変な作業になります。セットアップにかかる時間を無くし、あらかじめインストール、セットアップされた環境から始めることで、開発に集中できます。

含まれるもの

Redux, Navigation, FontAwsome, カスタムフォント、アイコン、画像のプレローディングのセットアプが完了しています。ボイラープレートのUIはベーシックなものになります。こちらは利用者がカスタマイズしやすいよう、必要最低限のセットアップのみにとどめています。

demo.gif

セットアップ

5分もかかりません。

  1. expoを持ってない方、こちらよりセットアップしてください。
  2. react-native-boilerplateより、zipファイルをDLしてください。
  3. app.jsonの name と slug 名を変更してください
app.json
"name": "your-app-name",
"slug": "your-app-name",
  1. yarn install もしくは npm install でプロジェクトをビルド
  2. expo start --ios

これでiPhoneのシミュレータが立ち上がります。
あとはコードを書くのみです。

ファイル構成

/src
  /components ... Button, Inputのような再利用可能な UI component 
     ∟ Button
  /modules ... Redux actions & state
  /routes
     ∟ /navigator ... ナビゲージョン関連
        ∟ drawer
        ∟ stack
        ∟ tab
     ∟ /subview ... ナビゲーションで使用するView
       ∟ sideMenu
  /scenes ... 画面一覧
     ∟ screen1
     ∟ screen2
  /styles ... アプリで使用するtheme, assets
     ∟ images
     ∟ fonts
     ∟ colors
  /utils
     ∟ store ... redux global state
     ∟ connector ... component と redux actions, stateをつなぐ

Navigationのカスタマイズ

/routes/navigator 配下でDrawer, Stack, Tab ナビゲーションそれぞれ宣言がなされています。もしDrawerが必要なく、Tab, Stack ナビゲーションのみが必要な場合、routes/routes.jsのimport を tabに変更してください。

/routes/routes.js
// import drawerNavigator from './navigator/drawer'
import tabNavigator from './navigator/tabs'
...

// const Router = createAppContainer(drawerNavigator)
const Router = createAppContainer(tabNavigator)
return <Router />

Stackナビゲーションのみが必要な場合も同様、import を navigation/stackへ変更してください。

Redux

ComponentとReduxの接続

ある画面から、Redux store と dispatch関数を使用する際、connectorを使用します。本来Redux store, dispatch関数を利用する際、react-reduxより、connectを取得し、mapStateToProps, mapDispatchToPropsでバインドする必要があったのですが、connectorを使用することで簡潔に記述することができます。サンプルを参照してください。connectorでcomponentをバインドしたのち、dispatch関数、stateをpropsより利用できます。

Reduxモジュールの分割

一つのファイルにstore, dispatch関数を追加し続けると、ファイルが肥大化し、ソースコードの管理が難しくなります。その場合、ファイルを分割する必要があります。全てのredux store, 関数は modulesフォルダ配下で管理しています。デフォルトでapp.module.jsがありますが、別のモジュールtest.module.jsを新たに追加するとします。/modules フォルダ配下に、以下のtest.module.jsを追加します。

/modules/test.module.js
// ------------------------------------
// Constants
// ------------------------------------

const KEY_CHECKED = 'KEY_CHECKED'

const initialState = {
  checked: false,
}

// ------------------------------------
// Actions
// ------------------------------------

export const isChecked = () => dispatch => dispatch({
  type: KEY_CHECKED,
  checked: true,
})

export const actions = {
  isChecked
}

// ------------------------------------
// Action Handlers
// ------------------------------------

const ACTION_HANDLERS = {
  [KEY_CHECKED]: (state, { checked }) => ({
    ...state,
    checked,
  }),
}

// ------------------------------------
// Reducer
// ------------------------------------

export default function reducer(state = initialState, action) {
  const handler = ACTION_HANDLERS[action.type]

  return handler ? handler(state, action) : state
}

次に、作成したモジュールを、connectorとつなげます。

utils/connector.js
import { actions as testActions } from '../modules/test.module'  // *追加
...

const mapDispatchToProps = (dispatch) => {
  const actionList = [
    { label: 'app', value: appActions },
    { label: 'test', value: testActions },    // *追加
  ]
...

さらに、storeにも追加します。

utils/store.js
import { actions as testActions } from '../modules/test.module'  // *追加
...

// Redux store config

const configureStore = (initialState = {}) => {
  const reducers = combineReducers({
    app,
    test,  // *追加
  })

あとは、サンプルのように、コンポーネントをconnectorでラップし、propsより、dispatch関数を呼び出したり、redux storeにアクセスします。

アセット

画像、フォント、色は、全て/styles配下で管理しています。それらを使用する際、毎回requireでインポートするのではなく、styleフォルダ配下で一限管理することにより、コードをより短く簡潔にし、新しい画像、フォント、色を追加した際にでも、どこに何を記述すればいいのかわかりやすくなります。

expample.js
import { Image } from 'react-native'
import { colors, fonts, images } from '../../styles'
...

const styles = {
  title: {
    fontFamily: fonts.openSan.regular,
    color: colors.purple,
  }
}
...

<Image source={images.logo_sm} style={{ width: 32, height: 32 }} />

※ 画像、フォントはアプリ起動時、前もって読み込むことで、表示がワンテンポ遅れる問題を解消しています。

公開リンク

expoで公開しています。
https://expo.io/@wataru/react-native-boilerplate

プロジェクトはこちらにあります。(Github)
https://github.com/WataruMaeda/react-native-boilerplate

最後まで読んでいただきありがとうございました。

Happy Cording!!

1
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
4