特定于平台的代码
在构建跨平台应用时,你将希望重用尽可能多的代码。可能会出现代码不同的情况,例如你可能想要为 Android 和 iOS 实现单独的可视组件。
¥When building a cross-platform app, you'll want to re-use as much code as possible. Scenarios may arise where it makes sense for the code to be different, for example you may want to implement separate visual components for Android and iOS.
React Native 提供了两种组织代码并按平台分离代码的方法:
¥React Native provides two ways to organize your code and separate it by platform:
-
使用
Platform
模块。¥Using the
Platform
module. -
使用 特定于平台的文件扩展名。
某些组件可能具有仅在一种平台上运行的属性。所有这些属性都标有 @platform
,并且在网站上它们旁边有一个小徽章。
¥Certain components may have properties that work on one platform only. All of these props are annotated with @platform
and have a small badge next to them on the website.
平台模块
¥Platform module
React Native 提供了一个模块来检测应用运行的平台。你可以使用检测逻辑来实现特定于平台的代码。当组件只有一小部分是特定于平台的时,请使用此选项。
¥React Native provides a module that detects the platform in which the app is running. You can use the detection logic to implement platform-specific code. Use this option when only small parts of a component are platform-specific.
import {Platform, StyleSheet} from 'react-native';
const styles = StyleSheet.create({
height: Platform.OS === 'ios' ? 200 : 100,
});
在 iOS 上运行时 Platform.OS
为 ios
,在 Android 上运行时为 android
。
¥Platform.OS
will be ios
when running on iOS and android
when running on Android.
还有一个 Platform.select
方法可用,给定一个键可以是 'ios' | 'android' | 'native' | 'default'
之一的对象,返回最适合你当前运行的平台的值。也就是说,如果你在手机上运行,则 ios
和 android
键将优先。如果未指定,将使用 native
键,然后使用 default
键。
¥There is also a Platform.select
method available that, given an object where keys can be one of 'ios' | 'android' | 'native' | 'default'
, returns the most fitting value for the platform you are currently running on. That is, if you're running on a phone, ios
and android
keys will take preference. If those are not specified, native
key will be used and then the default
key.
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 上具有绿色背景颜色,在其他平台上具有蓝色背景颜色。
¥This will result in a container having flex: 1
on all platforms, a red background color on iOS, a green background color on Android, and a blue background color on other platforms.
由于它接受 any
值,因此你还可以使用它返回特定于平台的组件,如下所示:
¥Since it accepts any
value, you can also use it to return platform-specific components, like below:
const Component = Platform.select({
ios: () => require('ComponentIOS'),
android: () => require('ComponentAndroid'),
})();
<Component />;
const Component = Platform.select({
native: () => require('ComponentForNative'),
default: () => require('ComponentForWeb'),
})();
<Component />;
检测 Android 版本 Android
¥Detecting the Android version
在 Android 上,Platform
模块还可用于检测应用运行的 Android 平台版本:
¥On Android, the Platform
module can also be used to detect the version of the Android Platform in which the app is running:
import {Platform} from 'react-native';
if (Platform.Version === 25) {
console.log('Running on Nougat!');
}
注意:Version
设置为 Android API 版本而不是 Android 操作系统版本。要查找映射,请参阅 安卓版本历史。
¥Note: Version
is set to the Android API version not the Android OS version. To find a mapping please refer to Android Version History.
检测 iOS 版本 iOS
¥Detecting the iOS version
在 iOS 上,Version
是 -[UIDevice systemVersion]
的结果,-[UIDevice systemVersion]
是操作系统当前版本的字符串。系统版本的示例是 "10.3"。例如,要检测 iOS 上的主版本号:
¥On iOS, the Version
is a result of -[UIDevice systemVersion]
, which is a string with the current version of the operating system. An example of the system version is "10.3". For example, to detect the major version number on iOS:
import {Platform} from 'react-native';
const majorVersionIOS = parseInt(Platform.Version, 10);
if (majorVersionIOS <= 9) {
console.log('Work around a change in behavior');
}
特定于平台的扩展
¥Platform-specific extensions
当特定于平台的代码更加复杂时,你应该考虑将代码拆分为单独的文件。React Native 将检测文件何时具有 .ios.
或 .android.
扩展名,并在其他组件需要时加载相关平台文件。
¥When your platform-specific code is more complex, you should consider splitting the code out into separate files. React Native will detect when a file has a .ios.
or .android.
extension and load the relevant platform file when required from other components.
例如,假设你的项目中有以下文件:
¥For example, say you have the following files in your project:
BigButton.ios.js
BigButton.android.js
然后你可以按如下方式导入组件:
¥You can then import the component as follows:
import BigButton from './BigButton';
React Native 会根据运行平台自动选择正确的文件。
¥React Native will automatically pick up the right file based on the running platform.
特定于原生的扩展(即与 NodeJS 和 Web 共享代码)
¥Native-specific extensions (i.e. sharing code with NodeJS and Web)
当需要在 NodeJS/Web 和 React Native 之间共享模块时,你也可以使用 .native.js
扩展,但它没有 Android/iOS 差异。这对于在 React Native 和 ReactJS 之间共享公共代码的项目特别有用。
¥You can also use the .native.js
extension when a module needs to be shared between NodeJS/Web and React Native but it has no Android/iOS differences. This is especially useful for projects that have common code shared among React Native and ReactJS.
例如,假设你的项目中有以下文件:
¥For example, say you have the following files in your project:
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
扩展名的情况下导入它,如下所示:
¥You can still import it without the .native
extension, as follows:
import Container from './Container';
专家提示:将你的 Web 打包程序配置为忽略 .native.js
扩展,以避免生产打包包中包含未使用的代码,从而减少最终打包包的大小。
¥Pro tip: Configure your Web bundler to ignore .native.js
extensions in order to avoid having unused code in your production bundle, thus reducing the final bundle size.