プラットフォーム固有のコード
クロスプラットフォームアプリを開発する際には、できるだけ多くのコードを再利用したいと思うでしょう。しかし、例えばAndroidとiOSで別々のビジュアルコンポーネントを実装したい場合など、コードを分けた方が理にかなっているシナリオも発生します。
React Nativeは、コードを整理しプラットフォームごとに分離するための2つの方法を提供しています。
Platform
モジュールの使用。- プラットフォーム固有のファイル拡張子の使用。
特定のコンポーネントには、1つのプラットフォームでのみ機能するプロパティがある場合があります。これらのプロパティはすべて@platform
で注釈されており、ウェブサイト上ではその横に小さなバッジが表示されます。
Platformモジュール
React Nativeは、アプリが実行されているプラットフォームを検出するモジュールを提供しています。この検出ロジックを使用して、プラットフォーム固有のコードを実装できます。コンポーネントのごく一部だけがプラットフォーム固有である場合に、このオプションを使用してください。
import {Platform, StyleSheet} from 'react-native';
const styles = StyleSheet.create({
height: Platform.OS === 'ios' ? 200 : 100,
});
Platform.OS
は、iOSで実行されている場合はios
に、Androidで実行されている場合はandroid
になります。
また、Platform.select
メソッドも利用可能です。これは、キーが'ios' | 'android' | 'native' | 'default'
のいずれかであるオブジェクトを与えると、現在実行しているプラットフォームに最も適した値を返します。つまり、スマートフォンで実行している場合、ios
とandroid
キーが優先されます。それらが指定されていない場合はnative
キーが使用され、次にdefault
キーが使用されます。
import {Platform, StyleSheet} from 'react-native';
const styles = StyleSheet.create({
container: {
flex: 1,
...Platform.select({
ios: {
backgroundColor: 'red',
},
android: {
backgroundColor: 'green',
},
default: {
// other platforms, web for example
backgroundColor: 'blue',
},
}),
},
});
これにより、コンテナはすべてのプラットフォームでflex: 1
となり、iOSでは赤色の背景色、Androidでは緑色の背景色、その他のプラットフォームでは青色の背景色になります。
any
型の値を受け入れるため、以下のようにプラットフォーム固有のコンポーネントを返すためにも使用できます。
const Component = Platform.select({
ios: () => require('ComponentIOS'),
android: () => require('ComponentAndroid'),
})();
<Component />;
const Component = Platform.select({
native: () => require('ComponentForNative'),
default: () => require('ComponentForWeb'),
})();
<Component />;
Androidバージョンの検出Android
Androidでは、Platform
モジュールを使用して、アプリが実行されているAndroidプラットフォームのバージョンを検出することもできます。
import {Platform} from 'react-native';
if (Platform.Version === 25) {
console.log('Running on Nougat!');
}
注: Version
はAndroid OSのバージョンではなく、Android APIのバージョンに設定されます。対応表については、Androidバージョン履歴を参照してください。
iOSバージョンの検出iOS
iOSでは、Version
は-[UIDevice systemVersion]
の結果であり、これは現在のオペレーティングシステムのバージョンを含む文字列です。システムバージョンの例は「10.3」です。例えば、iOSのメジャーバージョン番号を検出するには、次のようにします。
import {Platform} from 'react-native';
const majorVersionIOS = parseInt(Platform.Version, 10);
if (majorVersionIOS <= 9) {
console.log('Work around a change in behavior');
}
プラットフォーム固有の拡張子
プラットフォーム固有のコードがより複雑な場合は、コードを別々のファイルに分割することを検討してください。React Nativeは、ファイルに.ios.
または.android.
の拡張子が付いていることを検出し、他のコンポーネントから要求された際に関連するプラットフォームのファイルを読み込みます。
例えば、プロジェクトに以下のファイルがあるとします。
BigButton.ios.js
BigButton.android.js
そして、次のようにコンポーネントをインポートできます。
import BigButton from './BigButton';
React Nativeは、実行中のプラットフォームに基づいて適切なファイルを自動的に選択します。
ネイティブ固有の拡張子(例: NodeJSやWebとのコード共有)
モジュールをNodeJS/WebとReact Nativeの間で共有する必要があるが、Android/iOS間の違いがない場合は、.native.js
拡張子を使用することもできます。これは、React NativeとReactJSの間で共通のコードを共有するプロジェクトに特に役立ちます。
例えば、プロジェクトに以下のファイルがあるとします。
Container.js # picked up by webpack, Rollup or any other Web bundler
Container.native.js # picked up by the React Native bundler for both Android and iOS (Metro)
次のように、.native
拡張子なしでインポートすることもできます。
import Container from './Container';
プロのヒント: Webバンドラーが.native.js
拡張子を無視するように設定することで、本番バンドルに未使用のコードが含まれるのを防ぎ、最終的なバンドルサイズを削減できます。