介绍
多年来,随着媒体查询的出现和服务工作者的引入,构建对移动友好的 Web 应用程序变得更加容易。使用媒体查询,我们可以支持不同移动设备的屏幕尺寸。使用 Service Worker,我们可以实现推送通知和后台同步等功能。
React Native是由 Facebook 开发的多平台解决方案,可让您使用 JavaScript 构建移动应用程序。这些移动应用程序被认为是多平台的,因为它们编写一次并部署在多个平台上,例如 Android、iOS 和 Web。
在本教程中,您将使用 React Native 组件(如、和 )构建一个应用程序,该应用程序显示来自Random User API 的用户信息。该应用程序将使用React Native Web库在 Web 和移动设备上运行,它允许您在 Web 应用程序中使用 React Native 组件和 API。ScrollView
Text
Image
注意:本教程末尾记录的部署过程是特定于 Android 的。然而,对于那些对 iOS 部署感兴趣的人来说,这个过程可能仍然具有教育意义。
先决条件
要完成本教程,您需要:
- Node.js 的本地开发环境。遵循如何安装 Node.js 并创建本地开发环境。
- 熟悉 JavaScript。您可以查看如何在 JavaScript 中编码系列以了解更多信息。
- 熟悉反应。您可以查看我们的How To Code in React.js系列。
本教程最初是在 Node v10 时编写的。当时,依赖项包括react
v16.6.3、react-native
v0.9.8 和expo
v31.0.5。
本教程已通过 Node v14.2.0、npm
v6.14.5、16.13.1、react
v0.62.2react-native
和expo
v37.0.11 验证。
步骤 1 — 设置项目
在开始之前,您需要设置项目并安装项目依赖项。
您将使用Create React App来引导您的应用程序。您正在使用 Create React App,因为它可以配置为 React Native 的别名。
要使用 Create React App 引导您的应用程序,请在终端中运行以下命令:
- npx create-react-app random-people
注意:本教程采用采用现有 React 应用程序并将其转换为 React Native 的方法。另一种等效方法是使用npx react-native init
.
导航到您的新项目目录:
- cd random-people
你会为一些最新的JavaScript API等来安装polyfills Promise
,Array.from
等等,因为transpiler不提供这些。
运行以下命令安装项目的开发依赖:
- npm install --save-dev babel-plugin-module-resolver@4.0.0 babel-plugin-transform-object-rest-spread@6.26.0 babel-plugin-transform-react-jsx-source@6.22.0 babel-preset-expo@8.1.0
这babel-plugin-module-resolver
是一个在使用 Babel 编译时解析您的项目模块的插件。您将使用这个包的别名react-native
,以react-native-web
建立项目配置的时候。
我们将使用Expo来构建和运行新的应用程序。Expo 是一个围绕 React Native 构建的开源工具链,用于构建 Android 和 iOS 应用程序。它提供对系统功能的访问,如相机和存储。
注意:如果您有兴趣稍后部署您的应用程序,您将需要一个 Expo 帐户。
首先,在全球安装 Expo CLI:
- npm install --global expo-cli@3.25.1
接下来,在本地安装 Expo:
- npm install expo@37.0.0
然后,安装 React Native 和 React Native Web:
- npm install react-native@0.62.2 react-native-web@0.12.2 react-art@16.13.1
下载运行和构建应用程序所需的包后,下一步是设置配置文件。创建一个.babelrc
在项目根目录中调用的文件:
- nano .bablerc
将以下代码添加到文件中以配置您的项目将使用的转译器:
{
"presets": ["babel-preset-expo"],
"env": {
"development": {
"plugins": [
"transform-object-rest-spread",
"transform-react-jsx-source"
]
}
},
"plugins": [
[
"module-resolver",
{
"alias": {
"^react-native$": "react-native-web"
}
}
]
]
}
创建一个名为 的文件app.json
:
- nano app.json
此文件用于应用程序的配置部分不代码属于,像应用程序name
,description
,sdkVersion
等,您可以找到可用的选项app.json
文件世博文档中。
添加以下代码行:
{
"expo": {
"sdkVersion": "37.0.0",
"name": "random-people",
"slug": "random-people",
"version": "0.1.0",
"description": "An application for displaying random people",
"primaryColor": "#ff8179"
}
}
注意:在测试本教程时,最新的 Expo SDK 版本为 37。稍后,您可能需要运行expo upgrade
(或手动修改您的app.json
和package.json
文件并运行npm install
)。请参阅 Expo 文档以升级 SDK。
让我们更新package.json
文件以包含在 Android 和 iOS 模拟器上运行应用程序的命令。此外,您将包括main
引用App.js
文件的字段。该文件将作为expo-cli
. package.json
在编辑器中打开文件:
- nano package.json
修改文件,使其看起来像这样:
{
"name": "random-people",
"version": "0.1.0",
"private": true,
"main": "./App.js",
// ...
"scripts": {
"start-web": "react-scripts start",
"build-web": "react-scripts build",
"test-web": "react-scripts test",
"eject-web": "react-scripts eject",
"start-native" : "expo start",
"android": "expo start --android",
"ios": "expo start --ios",
"build:ios": "expo build:ios",
"build:android": "expo build:android"
},
// ...
}
运行npm run start-web
以运行应用程序并localhost:3000
在 Web 浏览器中访问以查看应用程序。
第 2 步 – 创建Home
组件
您的应用程序将通过 Random User API 显示用户。使用 API,您将收到返回用户的显示名称和头像。
在src
目录中,创建一个名为 的文件home.js
:
- nano src/home.js
将此代码添加到文件以定义组件:
import React from "react";
import { ScrollView, ActivityIndicator, StyleSheet } from "react-native";
class Home extends React.Component {
state = {
users: [],
loading: true
};
componentDidMount() {
// TODO: get users
}
render() {
return (
<ScrollView
noSpacer={true}
noScroll={true}
style={styles.container}
>
<ActivityIndicator
style={[styles.centering, styles.gray]}
color="#ff8179"
size="large"
/>
</ScrollView>
);
}
}
var styles = StyleSheet.create({
container: {
backgroundColor: "whitesmoke"
},
centering: {
alignItems: "center",
justifyContent: "center",
padding: 8,
height: '100vh'
},
});
export default Home;
该Home
组件呈现一个包含组件元素的ScrollView组件。
目前,该组件显示一个ActivityIndicator;当对 API 的调用完成时,这将被用户列表替换。
您将使用StyleSheet组件为元素创建样式。这允许您使用类似于 CSS 属性的属性来设置组件的样式。
让我们创建一个从 Random User API 获取随机用户的方法。该方法将在componentDidMount
生命周期中被调用。
更新home.js
组件以包含该getUsers
方法:
// ...
class Home extends React.Component {
state = {
// ...
};
componentDidMount() {
this.getUsers();
}
async getUsers() {
const res = await fetch("https://randomuser.me/api/?results=20");
const { results } = await res.json();
this.setState({ users: [...results], loading: false });
}
render() {
// ...
}
}
// ...
您可以使用本机Fetch
API轻松发出请求。请求的结果被解析并添加到状态。请求完成后,您将ActivityIncidator
通过设置loading
为 false 来隐藏。
第 3 步 – 创建App
组件
在AppComponent
适用于该应用程序的逻辑。您将通过添加显示本机组件的逻辑来更新 Create React App 创建的默认视图,以适应您的应用程序的视图。
替换src/App.js
文件内容:
import React from 'react';
import { AppRegistry, StyleSheet, View } from 'react-native';
import Home from './home';
class App extends React.Component {
render() {
return (
<View style={styles.appContainer}>
<Home />
</View>
);
}
}
const styles = StyleSheet.create({
appContainer: {
flex: 1,
},
});
AppRegistry.registerComponent('App', () => App);
export default App;
在上面的代码段中,您<App>
使用AppRegistry
. 该AppRegistry是切入点的阵营本地应用程序。
此版本App.js
显示网页版。您将需要一秒钟App.js
来显示 React Native 版本。
在项目的根目录中复制src/App.js
一个新App.js
文件:
- cp src/App.js App.js
注意:请务必App.js
使用这些更改来修改项目根目录中的文件,以便在测试时与 Expo 一起使用。
更改 的路径很重要Home
。从./home
到./src/home
。
现在,您将创建<UserItem>
组件。
第 4 步 – 创建 UserItem
每个用户项目将使用一个View
组件显示。该视图组件是一个重要组成部分,它支持使用Flexbox的,造型和可访问的布局。View
每个项目的组件将在一个SwipeableFlatList
. 每个项目将显示用户的头像、姓名和电子邮件。
创建一个user-item.js
在src
目录中调用的文件:
- nano src/user-item.js
将以下代码添加到文件中:
import React from "react";
import { View, Image, Text, StyleSheet } from "react-native";
const UserItem = ({ item: user }) => {
return (
<View style={styles.row}>
<Image style={styles.rowIcon} source={user.picture.medium} />
<View style={styles.rowData}>
<Text style={styles.rowDataText}>
{`
${user.name.title}
${user.name.first}
${user.name.last}
`}
</Text>
<Text style={styles.rowDataSubText}>{user.email}</Text>
</View>
</View>
);
};
const styles = StyleSheet.create({
row: {
flexDirection: "row",
justifyContent: "center",
alignItems: "center",
padding: 15,
marginBottom: 5,
backgroundColor: "white",
borderBottomWidth: StyleSheet.hairlineWidth,
borderBottomColor: "rgba(0,0,0,0.1)"
},
rowIcon: {
width: 64,
height: 64,
marginRight: 20,
borderRadius: "50%",
boxShadow: "0 1px 2px 0 rgba(0,0,0,0.1)"
},
rowData: {
flex: 1
},
rowDataText: {
fontSize: 15,
textTransform: "capitalize",
color: "#4b4b4b"
},
rowDataSubText: {
fontSize: 13,
opacity: 0.8,
color: "#a8a689",
marginTop: 4
}
});
export default UserItem;
要显示每个用户的头像,您可以使用Image组件。该组件采用一个source
道具,它可以src
作为您在网络上使用的道具。您可以使用styles.rowIcon
属性进一步设置组件的样式。
接下来,您将创建UserList
以显示每个UserItem
.
第 5 步 — 创建 UserList
该FlatList
组件是一种在其列表呈现方法中性能良好的组件。它延迟加载列表中的项目,并且仅在用户滚动到列表底部时加载更多项目。TheSwipeableFlatList
是FlatList
React Native Web 提供的包装器,它使列表中的每个项目都可以滑动——因此每个项目在滑动时都会显示一组操作。
SwipeableFlatList
以前是 的一部分react-native
,但此后已被删除。要使用它,请安装以下软件包:
- npm install react-native-swipeable-lists@0.0.1
注意:或者,还有其他SwipeableFlatList
可用的实现。
让我们SwipeableFlatList
为从 API 返回的用户创建。SwipeableFlatList
从react-native-swipeable-lists
包中导入组件并更新渲染函数以显示列表。user-list.js
在src
目录中创建一个名为的文件:
- nano src/user-list.js
将此代码添加到文件中:
import React from "react";
import { SwipeableFlatList } from "react-native-swipeable-lists";
import UserItem from "./user-item";
const UserList = ({ users }) => {
return (
<SwipeableFlatList
data={users}
bounceFirstRowOnMount={true}
maxSwipeDistance={160}
renderItem={UserItem}
/>
);
};
export default UserList;
data
:这个道具代表将被馈送到列表中每个项目的数据。所述data
支柱通常是一个数组。bounceFirstRowOnMount
: 如果为 true,它会在列表中的第一个项目上触发反弹动画,表示它有隐藏的动作。maxSwipeDistance
:此道具为每个项目设置最大可滑动距离。renderItem
:这个道具接受一个渲染项目的函数;此函数将传递一个item
包含要显示的数据的道具。
注意:或者,还有其他SwipeableFlatList
可用的实现。
让我们更新src/home.js
文件以包含新的UserList
.
打开src/home.js
文件:
- nano src/home.js
并使用以下内容更新它:
import React from "react";
import { ScrollView, ActivityIndicator, StyleSheet } from "react-native";
import UserList from "./user-list";
class Home extends React.Component {
state = {
// ...
};
componentDidMount() {
// ...
}
render() {
return (
<ScrollView
noSpacer={true}
noScroll={true}
style={styles.container}
>
{this.state.loading ? (
<ActivityIndicator
style={[styles.centering, styles.gray]}
color="#ff8179"
size="large"
/>
) : (
<UserList users={this.state.users} />
)}
</ScrollView>
);
}
}
// ...
export default Home;
现在,如果您localhost:3000
在浏览器上访问,您将看到一个用户列表。
您添加了一个SwipeableFlatList
组件,这意味着每个用户项目都是可滑动的。接下来,添加用户可以滑动以显示的操作。
第 6 步 – 向项目添加操作
列表中的每个项目都将提供一组操作,当向左滑动时将显示这些操作。操作集将使用TouchableHighlight
View 组件包含的组件。该TouchableHighlight当你需要观众来接触,或多或少表现得像一个按钮响应组件使用。
user-actions.js
在src
目录中创建一个名为的文件:
- nano src/user-actions.js
将以下内容添加到文件中:
import React from "react";
import { View, TouchableHighlight, Text, Alert, StyleSheet } from "react-native";
const UserActions = () => {
return (
<View style={styles.actionsContainer}>
<TouchableHighlight
style={styles.actionButton}
onPress={() => {
Alert.alert("Tips", "You could do something with this edit action!");
}}
>
<Text style={styles.actionButtonText}>Edit</Text>
</TouchableHighlight>
<TouchableHighlight
style={[styles.actionButton, styles.actionButtonDestructive]}
onPress={() => {
Alert.alert(
"Tips",
"You could do something with this remove action!"
);
}}
>
<Text style={styles.actionButtonText}>Remove</Text>
</TouchableHighlight>
</View>
);
};
const styles = StyleSheet.create({
actionsContainer: {
flex: 1,
flexDirection: "row",
justifyContent: "flex-end",
alignItems: "center",
padding: 10
},
actionButton: {
padding: 10,
color: "white",
borderRadius: 6,
width: 80,
backgroundColor: "#808080",
marginRight: 5,
marginLeft: 5
},
actionButtonDestructive: {
backgroundColor: "#ff4b21"
},
actionButtonText: {
textAlign: "center"
}
});
export default UserActions;
该TouchableHighlight
组件采用onPress
在单击该组件时触发的回调。每个回调都会触发一次Alert
显示。样式也应用于包含视图组件和页面上的其他组件。
要包含对每个用户项的操作,请更新UserList
组件以包含renderQuickActions
prop,它也带有一个函数。
打开src/user-list.js
并修改它:
// ...
import UserActions from "./user-actions";
const UserList = ({ users }) => {
return (
<SwipeableFlatList
// ...
renderQuickActions={UserActions}
/>
);
};
export default UserList;
现在,当您在任何用户项上向左滑动时,它会显示两个操作 –Edit
和Remove
。
第 7 步 – 添加Header
组件
现在您已成功获取用户并使用本机组件显示它们,让我们添加一个标题。使用该SafeAreaView
组件,您将创建一个具有定义边界的区域。这将作为您的应用程序的标头。
header.js
在src
目录中创建一个名为的新文件:
- nano src/header.js
将以下代码添加到文件中:
import React from 'react';
import { SafeAreaView, View, Text, StyleSheet } from 'react-native';
const Header = ({ onBack, title }) => (
<SafeAreaView style={styles.headerContainer}>
<View style={styles.header}>
<View style={styles.headerCenter}>
<Text accessibilityRole="heading" aria-level="3" style={styles.title}>{title}</Text>
</View>
</View>
</SafeAreaView>
);
const styles = StyleSheet.create({
headerContainer: {
borderBottomWidth: StyleSheet.hairlineWidth,
borderBottomColor: '#ff4e3f',
backgroundColor: '#ff8179',
},
header: {
padding: 10,
paddingVertical: 5,
alignItems: 'center',
flexDirection: 'row',
minHeight: 50
},
headerCenter: {
flex: 1,
order: 2
},
headerLeft: {
order: 1,
width: 80
},
headerRight: {
order: 3,
width: 80
},
title: {
fontSize: 19,
fontWeight: '600',
textAlign: 'center',
color: 'white'
},
});
export default Header;
现在,让我们将Header
组件添加到App
组件中。这将在应用程序顶部显示一个简单的标题。
更新App.js
文件以包含Header
组件:
// ...
import Header from './header';
class App extends React.Component {
render() {
return (
<View style={styles.appContainer}>
<Header title="Random People" />
<Home />
</View>
);
}
}
// ...
export default App;
应用程序刷新后,标题将添加到应用程序的顶部。
注意:请务必App.js
使用这些更改来修改项目根目录中的文件,以便在测试时与 Expo 一起使用。
更改 的路径很重要Header
。从./header
到./src/header
。
让我们看看可用于在移动设备上测试应用程序的各种方法。
第 8 步 — 在移动设备上进行测试
该expo-cli
实用程序提供了各种方法来测试移动设备上的应用程序。第一种是使用运行应用程序后生成的 URL。您可以在移动浏览器上访问此 URL 来测试应用程序。
为了在移动设备上测试应用程序,expo-cli
提供了各种方法来测试移动应用程序。第一种是使用运行应用程序后生成的 URL。可以在您的移动浏览器上访问此 URL 以测试应用程序。
在您的项目中运行以下命令以使用 Expo 运行应用程序:
- npm run start-native
Expo 通常在 port 上启动您的应用程序19002
,因此请访问localhost:19002
以查看 Expo 开发工具。在开发工具中,您可以将链接作为短信或电子邮件发送到您的手机。
您可以选择三个连接选项中的任何一个 — 外部隧道、LAN 或本地连接。对于本地连接,您的手机和开发计算机必须连接到同一网络,但无论如何隧道都可以工作。
在移动设备上进行测试的下一个选项是使用模拟器。使用Android studio或Xcode,您可以为各自的平台启动模拟器。下载并安装适用于所选平台的工具——适用于 iOS 的 Xcode 或适用于 Android 的 Android Studio。
安装后,在任何模拟器上运行npm run android
或npm run ios
启动应用程序。
步骤 9 — 部署应用程序
注意:这是完成本教程不需要的可选步骤。对于从项目创建到应用商店提交的工作流程的教育目的,应该考虑这一点。
您将把应用程序部署到 Android Play 商店。为此,您需要更新app.json
文件以包含Android特定属性。打开app.json
文件并更新文件以包含该android
字段:
{
"expo": {
"sdkVersion": "37.0.0",
"name": "random-people",
"slug": "random-people",
"version": "0.1.0",
"description": "An application for displaying random people",
"primaryColor": "#ff8179",
"android": {
"package": "com.random.people"
}
}
}
该android.package
字段是一个唯一值,将代表您在应用商店中的包。您可以在此处阅读有关包命名约定的更多信息。
更新文件后,运行npm run build:android
命令。
此命令将向您显示一个提示,要求您提供一个密钥库或生成一个新的密钥库。如果您有现有的密钥库,您可以选择此选项或让 expo 为您的应用程序生成一个。
完成后,将为您的应用程序生成一个下载链接。单击此链接将触发下载您的 APK。
要将下载的 APK 部署到 Android Play 商店,请访问Play 管理中心创建一个帐户。创建帐户后,您需要支付 25 美元的注册费才能继续。完成注册过程后,请访问此页面并按照步骤将您的应用程序上传到 Play 商店。
结论
使用 React Native Web 和 React Native 库,您创建了一个可以使用本机组件部署在多个平台上的应用程序。构建多平台应用程序从未如此简单。
您可以在 GitHub 上查看演示的源代码。
如果您想了解有关 React 的更多信息,请查看我们的How To Code in React.js系列,或查看我们的 React 主题页面以获取练习和编程项目。