平台特定代码
在构建跨平台应用时,您希望尽可能地重用代码。某些情况下,代码可能需要有所不同,例如,您可能希望为 Android 和 iOS 实现单独的视觉组件。
React Native 提供两种方式来组织代码并按平台进行分离
- 使用
Platform
模块。 - 使用 平台特定文件扩展名。
某些组件可能具有一些仅在一个平台上有效的属性。所有这些属性都用 @platform
进行注释,并在网站上显示一个小徽章。
Platform 模块
React Native 提供了一个模块,用于检测应用运行的平台。您可以使用检测逻辑来实现平台特定代码。当只有组件的一小部分是平台特定的时,可以使用此选项。
import {Platform, StyleSheet} from 'react-native';
const styles = StyleSheet.create({
height: Platform.OS === 'ios' ? 200 : 100,
});
在 iOS 上运行时,Platform.OS
将为 ios
,在 Android 上运行时将为 android
。
还提供了一个 Platform.select
方法,它接受一个对象,其中键可以是 'ios' | 'android' | 'native' | 'default'
中的一个,并返回当前运行平台上最合适的 value。也就是说,如果您在手机上运行,则 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 API 版本,而不是 Android 操作系统版本。要查找映射,请参阅 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
扩展名,以避免在生产包中包含未使用的代码,从而减小最终包的大小。