ionic-reactことはじめとIonicでのReactライフサイクルなど

この記事は、React Advent Calendar 2019の第一日目です。 IonicでReactが使えるようになってしばらく経ちました。まだちゃんと触ったりドキュメントを終えていなかったので、ざっと動かして調べて […]

広告ここから
広告ここまで

目次

    この記事は、React Advent Calendar 2019の第一日目です。

    IonicでReactが使えるようになってしばらく経ちました。まだちゃんと触ったりドキュメントを終えていなかったので、ざっと動かして調べてみたまとめです。

    事前準備

    Node.jsのバージョンを以下のいずれか以上にしましょう。ionic startで立ち上げるテンプレートに@typescript-eslint/eslint-pluginが入っていることがあります。

    こいつがNode.jsのバージョン指定をしているため、以下のバージョン以下のNode.jsを使っているとセットアップが落ちます。

    • 8.10.0以上
    • 10.13.0以上
    • 11.10.1以上

    IonicのCLIを(記事執筆時点の)最新版にします。

    $  npm i -g ionic@latest
    updated 1 package in 15.206s
    
    $ ionic -v
    5.4.9

    プロジェクトのセットアップ

    早速プロジェクトを立ち上げます。今回はあえて対話式にしていますが、オプションをつけることで1発で立ち上げも可能です。

    $ ionic start
    
    Every great app needs a name! 😍
    
    Please enter the full name of your app. You can change this at any time. To bypass this prompt next time, supply name,
    the first argument to ionic start.
    
    ? Project name: YOUR_APP_NAME

    FrameworkをReactにする

    プロジェクト名を指定すると、フレームワークが選べます。ここはおそらく将来的に他のフレームワークも出てくるのでしょう。

    
    Pick a framework! 😁
    
    Please select the JavaScript framework to use for your new app. To bypass this prompt next time, supply a value for the
    --type option.
    
    ? Framework: 
      Angular | https://angular.io 
    ❯ React   | https://reactjs.org

    テンプレートを指定する

    続いてテンプレートを指定します。blankで一から作るのも良いですが、今回はあえてconferenceでがっつり作ってあるやつを選んでみます。

    Starter templates are ready-to-go Ionic apps that come packed with everything you need to build your app. To bypass this
    prompt next time, supply template, the second argument to ionic start.
    
    ? Starter template: 
      blank      | A blank starter project 
      sidemenu   | A starting project with a side menu with navigation in the content area 
      tabs       | A starting project with a simple tabbed interface 
    ❯ conference | A kitchen-sink application that shows off all Ionic has to offer 

    ちなみにここで以下のエラーが出た場合は、Node.jsのバージョンが古いです。 Nodeのバージョンをアップデートしたのち、cd YOUR_APP_NAME && yarnを実行してリトライしてやりましょう。

    error @typescript-eslint/[email protected]: The engine "node" is incompatible with this module. Expected version "^8.10.0 || ^10.13.0 || >=11.10.1". Got "10.5.0"
    error Found incompatible module.
    info Visit https://yarnpkg.com/en/docs/cli/install for documentation about this command.
    [ERROR] An error occurred while running subprocess yarn.
            
            yarn install --non-interactive exited with exit code 1.
            
            Re-running this command with the --verbose flag may provide more information.

    こっちのメッセージが出たら準備完了です。

    INFO] Next Steps:
           
           - Go to your cloned project: cd ./YOUR_APP_NAME
           - Run ionic serve within the app directory to see your app
           - Build features and components: https://ion.link/scaffolding-docs
           - Run your app on a hardware or virtual device: https://ion.link/running-docs

    Ionic Reactアプリをローカル起動する

    続いてローカル起動させてみましょう。

    $ cd ./YOUR_APP_NAME
    $ ionic serve
    > react-scripts start
    [react-scripts] Starting the development server...

    わかる人にはわかるやつですが、react-scriptsが出てくるということは、Ionic Reactはcreate-react-appを使ってセットアップされています。ちなみにドキュメントにもそう書かれていました

    localhostのURLが出てこない場合

    conferenceのtemplateですが、この記事をかいている時点だと、ionic serveでlocalhostの何番で起動したかがわからなくなっています。

    > react-scripts start
    [react-scripts] Starting the development server...
    [react-scripts] 
    [react-scripts] Compiled with warnings.
    [react-scripts] 
    [react-scripts] ./src/components/SessionListItem.tsx
    [react-scripts]   Line 1:25:  'useState' is defined but never used  @typescript-eslint/no-unused-vars
    [react-scripts]   Line 2:26:  'IonAlert' is defined but never used  @typescript-eslint/no-unused-vars
    [react-scripts] ./src/data/connect.tsx
    [react-scripts]   Line 1:29:  'useEffect' is defined but never used                                                                                                                                                                                                   @typescript-eslint/no-unused-vars
    [react-scripts]   Line 1:40:  'useState' is defined but never used                                                                                                                                                                                                    @typescript-eslint/no-unused-vars
    [react-scripts]   Line 39:8:  React Hook useMemo has a missing dependency: 'context'. Either include it or remove the dependency array. Outer scope values like 'mapDispatchToProps' aren't valid dependencies because mutating them doesn't re-render the component  react-hooks/exhaustive-deps
    [react-scripts]   Line 44:8:  React Hook useMemo has a missing dependency: 'dispatchFuncs'. Either include it or remove the dependency array                                                                                                                          react-hooks/exhaustive-deps
    [react-scripts] ./src/pages/SchedulePage.tsx
    [react-scripts]   Line 9:25:  'addFavorite' is defined but never used     @typescript-eslint/no-unused-vars
    [react-scripts]   Line 9:38:  'removeFavorite' is defined but never used  @typescript-eslint/no-unused-vars
    [react-scripts] Search for the keywords to learn more about each warning.
    [react-scripts] To ignore, add // eslint-disable-next-line to the line before.

    ESLintのwarningが先に出てきてしまっているという状態ですね。内容に合わせて修正すればOKではあります。

    本来はIssueなりPR出したりしないとかなと思いつつ、カレンダーに間にあわせるためにとりあえずここに書いてます。後でやります。

    もしURLが出てこない場合は、https://localhost:8100/tutorialを試してみてください。自分の場合はこれでいけました。

    Ionic Reactには独自のライフサイクルがある

    Reactであれば通常component[Did | Will]XXXuseXXXというライフサイクルメソッドを使います。Ionicの場合、これらのIonic版が用意されていますので、こちらを使うことになります。

    • ionViewWillEnter コンポーネントが表示されるアニメーションがはじまる時に発火します。
    • ionViewDidEnter コンポーネントが表示されるアニメーションが終了した時に発火します。
    • ionViewWillLeave コンポーネントを離脱するアニメーションがはじまる時に発火します。
    • ionViewDidLeave コンポーネントを離脱するアニメーションが終了した時に発火します。

    from: https://ionicframework.com/jp/docs/react/lifecycle

    React側で非推奨になったcomponentWillMount的に使えそうなメソッドがあるのが目につきますね。

    Tips: ionViewWillEnterはcomponentDidMount相当

    ぱっと見componentWillMountを使っちゃってるのかなと思えますが、実装をみるcomponentDidMountにいるっぽいです。

    詳しく追いきれていませんが、Reactのライフサイクル -> Ionicのライフサイクルになるイメージでしょうか。

    Ionic Reactでは、なるべくIonicのライフサイクルを利用しよう

    ドキュメントにも記載されていますが、React側のライフサイクルを使うと、意図しない動きになることがある様子です。

    ただし、Ionic Reactはページのライフタイムを管理するため、特定のイベントが期待どおりに発生しない場合があります。 たとえば、最初にページが表示されたときは componentDidMount が起動しますが、ページから移動した時にIonicはページをDOMツリーに保持しているため、その後の当該ページへのアクセスでは componentDidMount を再度呼び出さない場合があります。 

    https://ionicframework.com/jp/docs/react/lifecycle

    Reactのライフサイクルも使えるが、なるべくIonic側のライフサイクルにのる必要がありそうです。

    広告ここから
    広告ここまで
    Home
    Search
    Bookmark