IonicReact v7とsetupIonicReactのかゆいところ
Ionicは昔に比べて素晴らしい代物になったと本当に感じていマス。
Cordova派生のAngularのみ対応だったものがReactでもVueでもハイブリットアプリを開発できるようになっている。用意されているのは現在はコマンドラインツールとコンポーネントのみで大分スリムにミニマムになリマした。
しかし対応しているJSライブラリ(フレームワーク)が増えた分メンテする規模も増え、コミッターは難しさを感じながら運用しているのではないかと勝手に推測している。アップデートの速さから各々の修正でまた細々とバグを残してしまう、それが物語っているではないかと感じています。
細々とやらないといけないところがたくさんあるゆえに大きな問題などは一旦スルーしようとしてしまうのが世の常かもしれません。
今回はIonicReact v7アップグレードによって、setupIonicReactの痒いところの一旦の解決策を記載してみようかと考えている。
解決したい
ページによって下記の仕様などがある
-
NavigationBottomBar
を非表示させたい -
スワイプ
で戻ることができるようにしたい
問題点
IonicReact v7では react-router v6
への対応がなされなかったこと
これに尽きる。
(Ionic側のコードをのぞいていくとルーティングの履歴でページアニメーション実装などをコンテキスト化しているので対応することの難しさは理解できる)
ご存じの方もいると思うが、react-router v6 では破壊的変更が行われている。しかし素敵な実装もあり、エンドポイントごとのリアクティブの実装。つまり任意のエンドポイント内でのページ間の実装が可能になっていると言える。
このことが可能となり上記のようなタブ間でのタブ表示非表示やスワイプで戻るような処理を容易く可能としている。
解決策
タブやスワイプなどのフラグをメモリ管理を行い。任意の各親ページで設定を行う。
jotaiを使用する
- models/platform.ts
今回はダークモードなどの設定は省かせていただきます。
swipeBackEnabled
はIonicConfig
から継承しています。
import { IonicConfig } from '@ionic/core';
/**
* 参考URL:
* https://ionicframework.com/docs/ja/react/config
* @interface
*/
export interface PlatformConfig extends IonicConfig {
isSubPage?: boolean;
isDarkMode?: boolean;
};
- stores/platform.ts
import { atom } from 'jotai';
import { PlatformConfig } from 'models/platform';
/**
* @interface
*/
export const curPlatformConfigState = atom<PlatformConfig>({
isSubPage: false,
isDarkMode: false,
swipeBackEnabled: false,
});
- App.tsx (or 任意のルーティング設定しているファイル)
IonTabBar
のhidden
プロパティで随時表示非表示を行います
const config = useAtomValue(curPlatformConfigState);
setupIonicReact(config);
....
<IonTabs>
<IonRouterOutlet>
...
</IonRouterOutlet>
<IonTabBar
slot={"bottom"}
hidden={config.isSubPage}
>
...
</IonTabBar>
</IonTabs>
- 各ページ (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