Platform Specific Extensions でOSごとにコンポーネントを分岐させる
React Native にてプラットフォームに沿ってコンポーネントを分ける場合のやり方の紹介です。 iOS の場合はこう、Androidの場合はこう、といった分岐をしたい場合の実装方法です。
大きくは以下の 2種類あります。
- Platform モジュール
- Platform Specific Extensions
それぞれ紹介と実装の際のコツのメモです。
Platform モジュール
以下で利用するものです。1度くらいは使ったことあるのではないでしょうか。
import { Platform } from "react-native"
Platform.OS
で現在のOSの種類が取得できます。switch文などを使って、ios
もしくはandroid
のどちらに一致するかで処理を分岐させれば意図した実装ができます。
他にも以下のようにselect を使えば、モジュールで分岐を書くこともできます。
const valur = Platform.select({
ios: 'ios です',
android: 'android です',
});
Platform.Version
でOSのバージョンを取得することも可能なので覚えておきましょう。
Platform Specific Extensions
もう 1つの方法として、Platform Specific Extensions
という仕組みがあります。
こちらはios用とAndroid用でコンポーネントの定義ファイルを分けて用意しておくことで、それぞれの環境で該当するものが読み込まれるというものです。
実装
たとえば、component.tsx
をOSごとに分岐させる場合、iOS用のコンポーネントはcomponent.ios.tsx
。Android用はcomponent.android.tsx
というようにファイルを用意します。
利用する時はimport { component } from "./component";
とすることでOSごとに対応する定義ファイルがimport されます。
TypeScript の型を解決
上記のように実装した場合にTypeScriptだと型のエラーが出力されてしまいます。
これは、同じディレクトリに型を定義したファイルを設置することで解決できます。上記の場合なら component.d.ts
というファイルを設置します。
以下のように型を定義することで、import する際の型の解決に加えて、iOSとAndroidのコンポーネント間の差分のチェックを行うこともできます。
import { component as ios } from "./component.ios";
import { component as android } from "./component.android";
declare var test: typeof ios;
declare var test: typeof android;
export * from "./component.ios";
おわりに
実装の方法は好みでいいのですが、あえてメリットを考えてみましょう。 Platform モジュールを使う場合は、分岐の処理や他方のOSの処理もバンドルされるので、その分容量が大きくなります。 Platform Specific Extensions の方が、ビルドした際にそれぞれのOSのコンポーネントファイルのみをバンドルできるので容量が小さくなります。
とはいえ、大概の場合は少しの差になります。よほどOSごとの処理が大きい場合はその恩恵を受けられます。
それよりも、ファイルを別にすることでコードが読みやすい・管理しやすいといった恩恵もあるので、そちらの方が嬉しいですね。