🐈

IonicReact v7とsetupIonicReactのかゆいところ

2023/08/09に公開

https://ionicframework.com/

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

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

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

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

解決したい

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

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

問題点

IonicReact v7では 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への対応にならないでしょう

IonicはIonReactRouterというタグの中で遷移アニメーションを行なっているのでreact-router v6への対応はまずないでしょう。しかし上記の方法で行えば各親ページに設定しているものの影響範囲が少ないゴミコードとなるだけなので、任意のタイミングで削除するだけでよいのではないでしょうか。

Discussion