📱

IonicReact v6とsetupIonicReactのかゆいところ

2022/05/06に公開約2,600字

https://ionicframework.com/

Ionicは昔に比べて素晴らしい代物になったと本当に感じている。
Cordova派生のAngularのみ対応だったものがReactでもVueでもハイブリットアプリを開発できるようになっている。用意されているのは現在はコマンドラインツールとコンポーネントのみで大分スリムにミニマムになった。

だが対応しているJSライブラリ(フレームワーク)が増えた分メンテする規模も増え、コミッターは難しさを感じながら運用しているのではないかと勝手に推測している。アップデートの速さから各々の修正でまた細々とバグを残してしまう、それが物語っているではないかと感じている。

細々とやらないといけないところがたくさんあるゆえに大きな問題などは一旦スルーしようとしてしまうのが世の常なのか。

今回はIonicReact v6へアップグレードによって、setupIonicReactの痒いところの一旦の解決策を記載してみようかと考えている。

解決したい

ページによって下記の仕様などがある

  • NavigationBottomBar を非表示させたい
  • スワイプ で戻ることができるようにしたい

問題点

IonicReact v6では react-router v6 への対応がなされなかったこと

これに尽きる。
 (Ionic側のコードをのぞいていくとルーティングの履歴でページアニメーション実装などをコンテキスト化しているので対応することの難しさは理解できる)

ご存じの方もいると思うが、react-router v6 では破壊的変更が行われている。しかし素敵な実装もあり、エンドポイントごとのリアクティブの実装。つまり任意のエンドポイント内でのページ間の実装が可能になっていると言える。

このことが可能となり上記のようなタブ間でのタブ表示非表示やスワイプで戻るような処理を容易く可能としている。

解決策

タブやスワイプなどのフラグをメモリ管理を行い。任意の各親ページで設定を行う。

jotaiを使用する

https://jotai.org
  1. models/platform.ts
    今回はダークモードなどの設定は省かせていただく
    swipeBackEnabledIonicConfig から継承している
import { IonicConfig } from '@ionic/core';

/**
 * 参考URL:
 * https://ionicframework.com/docs/ja/react/config
 * @interface
 */
export interface PlatformConfig extends IonicConfig {
  isSubPage?: boolean;
  isDarkMode?: boolean;
};

  1. stores/platform.ts
import { atom } from 'jotai';
import { PlatformConfig } from 'models/platform';

/**
 * @interface
 */
export const curPlatformConfigState = atom<PlatformConfig>({
  isSubPage: false,
  isDarkMode: false,
  swipeBackEnabled: false,
});

  1. App.tsx (or 任意のルーティング設定しているファイル)
    IonTabBarhidden プロパティで随時表示非表示を行う

const config = useAtomValue(curPlatformConfigState);
setupIonicReact(config);

....

<IonTabs>
  <IonRouterOutlet>
    ...
  </IonRouterOutlet>
  <IonTabBar
    slot={"bottom"}
    hidden={config.isSubPage}
  >
    ...
  </IonTabBar>
</IonTabs>
  1. 各ページ (ex. HogeListPage.tsx と HogeDetailPage.tsx)
    Ionicライフサイクル useIonViewWillEnter を使用して実際のレンダリングが始まる前に必要な設定を先に行っておく

ex. HogeListPage.tsx
タブ表示でスワイプで戻るようなことはさせたくない

useIonViewWillEnter(() => {
    // 初期設定
    setPlatformConfig({
      isSubPage: false,
      swipeBackEnabled: false,
    });
});

ex. HogeDetailPage.tsx
タブ非表示でスワイプでリストページに戻るようなことをさせたい

useIonViewWillEnter(() => {
    // 初期設定
    setPlatformConfig({
      isSubPage: true,
      swipeBackEnabled: true,
    });
});

react-router v6への対応になったら

IonicReactV6のままではreact-router v6への対応はまずないだろう。
先日v6.1.0へのアップデートがあったが対応がなかったので、対応はV7(今秋)だと思われる。

また任意のエンドポイント内、タブ間の処理が入れらるようになるので、各親ページでの設定が必要になくなる。

各親ページに設定しているものの影響範囲が少ないゴミコードとなるだけなので、任意のタイミングで削除するだけでよいのではなかろうか

Discussion

ログインするとコメントできます