ReactとIonicでアプリ開発ができる@ionic&#47reactを触ってみた

2019.02.20

どうも、クロスプラットフォーム開発の夢を捨てきれない@mottox2です。 クロスプラットフォーム開発の選択肢はReactNative, Flutter, Xamarinなどがありますが、つい最近にメジャーバージョンアップされたIonicをReactで書けるという話を聞いたので触ってみました。

@ionic/react 0.0.4(alpha)での動作を元にしているので、すぐに役立たない記事になると思うのでその当たりはご承知いただけると嬉しいです。Ionicは初見です。

検証につかったコードはこちら: mottox2-sandbox/ionic-react-app

@ionic/reactって?

IonicでReactを使うには @ionic/reactを使って進めていくようです。

@ionic/react 0.0.4のREADME.mdを見ながらやっていきます。 https://www.npmjs.com/package/@ionic/react/v/0.0.4

README.mdを見ると、次のようなことが書いてありました。(意訳)

なので、サンプルコードを見ながらcreate-react-appを使って簡単なアプリケーションを作ってみようと思います。

プロジェクトの設定

create-react-appでTypeScriptということで毎度おなじみのcreate-react-appのコマンドを叩いてみます。

$ npx create-react-app ionic-react-app --typescript
$ cd ionic-react-app
$ npm install @ionic/core @ionic/react
$ npm install react-router-dom

インストールした時点でpeer dependencyとしてreact-routerとreact-router-domが必要らしいのでreact-router-domもインストールしておきます。1

src/index.jsにregisterIonicの記述を追加します。(0.0.5でメソッドが削除されました)

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import { registerIonic } from '@ionic/react';

registerIonic()
ReactDOM.render(<App />, document.getElementById('root'));

準備は整ったので適当にUIを作っていきます。Ionicの知識はないのでドキュメントを頼りにします。AngularとReactの差分ですが、ドキュメントのion-appはIonAppに対応します。 src/App.jsを次のように変更しました。 UIコンポーネントは@ionic/react、全体のスタイルは@iconic/coreの方から呼び出します。

https://ionicframework.com/docs/api/ https://ionicframework.com/docs/layout/structure

import React, { Component } from 'react';
import { IonApp, IonHeader, IonToolbar, IonTitle, IonContent, IonButton } from '@ionic/react';
import logo from './logo.svg';
import './App.css';
import '@ionic/core/css/core.css';
import '@ionic/core/css/ionic.bundle.css';

class App extends Component {
  render() {
    return (
      <div id='app'>
        <IonApp>
          <IonContent>
            <IonHeader>
              <IonToolbar>
                <IonTitle>
                  IonicReactApp
                </IonTitle>
              </IonToolbar>
            </IonHeader>
            <img src={logo} className="App-logo" alt="logo" />
            <p>
              Edit <code>src/App.tsx</code> and save to reload.
            </p>
            <IonButton href="https://reactjs.org">Learn React</IonButton>
          </IonContent>
        </IonApp>
      </div>
    );
  }
}

export default App;

この状態でnpm run startを実行すると、次のように表示されました。無事IonicのコンポーネントをReactで呼び出すことができました。

localhost_3002_(iPhone 6_7_8).png (36.0 kB)

capacitorの追加

それでは今作ったものをiOSで動かしてみましょう。cordovaの後継として開発されているcapacitorを利用します。 capacitorの関連ライブラリをインストールして、npx経由でcap initを実行します。

$ npm install @capacitor/core @capacitor/cli
$ npx cap init

するとAppNameとAppIDの入力を求められるので適当に入力します。 入力が終わるとcapacitor.config.jsonというファイルが生成されるので、その中のwebDirwwwからbuildに書き換えます。

{
  "appId": "com.example.app",
  "appName": "App",
  "bundledWebRuntime": false,
  "webDir": "build"
}

その後npm run buildを行いReactのアプリケーションをビルドしましょう。ビルドされたものはbuild/に保存されます。 保存されていることが確認したら次のコマンドを実行してios用のプロジェクトを生成します。

$ npx cap add ios
$ npx cap sync ios

設定が正しければiosディレクトリが生成されます。 npx cap open iosを実行するとXcodeが開くので、アプリを実行するとシミュレーターが起動しアプリとして動作

スクリーンショット 2019-02-19 22.48.30.png (355.1 kB)

※ StatusBarとかぶってしまったので、divタグにmarginTopをつける感じで暫定対応しています。(求む、対応策)

@rdlaboさんより https://qiita.com/rdlabo/items/e05ae0b8986c36af9665 を読むといいかもというアドバイスをいただきました。 見ていった結果iPhoneのsafe-area-inset(iPhoneのノッチに対応する部分の数値を検出するもの)のコードにたどり着きそれが有効になっていないことがわかりました。 調べた結果safe-area-insetを有効にするには、viewportを適切に設定する必要があるとわかりviewport-fit=coverを設定することで上記の問題は解決しました。

さいごに

そもそも日本語情報には期待していないのですが、英語情報ですら今はライブラリのREADME.mdとサンプルアプリが1つみたいな状況です。つらい。 ネイティブな機能に関してはまだ触ってないので、暇な時に触れればいいかなと思っています。

JSでアプリを書くという意味ではReactにはすでにReactNativeが存在しているので、流行るのかはわかりません。ただ、ReactNativeはNativeからWeb、IonicはDOMからNativeと思想が違うのでそういった面では面白いと思いました。Ionic + Vueはなかなか相性が良さそうです。(WeexやVueNativeよりは筋がよさそう)

ただし、私はIonic初心者なので経験者でなにか言いたいことがあればTwitterやDMで連絡もらえると嬉しいです。

注釈

  1. react-routerはreact-router-domの依存ライブラリなのでreact-router-domを入れておけば問題ありません。