Xây dựng ứng dụng web thân thiện với thiết bị di động với React Native Web
Trong những năm qua, việc xây dựng các ứng dụng web thân thiện với thiết bị di động đã trở nên dễ dàng hơn với sự ra đời của các media query và sự ra đời của các nhân viên dịch vụ. Sử dụng media query , ta có thể tạo các ứng dụng web có hình dạng khác nhau khi xem trên thiết bị di động. Service worker, với các tính năng mạnh mẽ của họ, hiện các ứng dụng web với sức mạnh mà chỉ các ứng dụng root mới được biết đến, như thông báo đẩy và đồng bộ hóa nền, trong số các tính năng khác.React Native là một giải pháp đa nền tảng do Facebook phát triển cho phép bạn tạo ứng dụng di động bằng JavaScript. Các ứng dụng dành cho thiết bị di động này được coi là đa nền tảng vì chúng được viết một lần và được triển khai trên nhiều nền tảng, như Android, iOS và web.
Trong hướng dẫn này, bạn sẽ xây dựng một ứng dụng hiển thị thông tin user từ [API user ngẫu nhiên] ( https://randomuser.me/ bằng cách sử dụng các thành phần React Native như ScrollView, Text và Image. Ứng dụng sẽ chạy cả trên web và thiết bị di động sử dụng thư viện React Native Web , cho phép bạn sử dụng các thành phần và API React Native trong các ứng dụng web.
Yêu cầu
Để hoàn thành hướng dẫn này, bạn cần :
- Môi trường phát triển local cho Node.js. Làm theo cách cài đặt Node.js và tạo môi trường phát triển local
- Một số quen thuộc với JavaScript. Bạn có thể xem loạt bài Cách viết mã trong JavaScript để tìm hiểu thêm.
- Làm quen với React. Bạn có thể làm theo hướng dẫn chính thức về React tại đây để bắt đầu với React.
Bước 1 - Tạo dự án
Trước khi bắt đầu, ta cần cài đặt dự án và cài đặt các phần phụ thuộc của dự án. Ta sẽ sử dụng Create React App để khởi động ứng dụng của ta . Ta đang sử dụng Create React App vì nó có thể được cấu hình thành alias React Native. Ta sẽ cài đặt polyfills cho một số API JavaScript mới nhất như Promise
, Array.from
, v.v., vì trình chuyển tiếp không cung cấp những API đó.
Để khởi động ứng dụng của bạn bằng Tạo ứng dụng React, hãy chạy lệnh sau:
- npx create-react-app random-people
Chạy lệnh sau để cài đặt các phụ thuộc phát triển của dự án. Nếu bạn đang sử dụng Yarn, hãy sử dụng lệnh này:
- yarn add --dev babel-plugin-module-resolver babel-plugin-transform-object-rest-spread babel-plugin-transform-react-jsx-source babel-preset-expo
Nếu bạn đang sử dụng npm
, hãy sử dụng lệnh này:
- npm install --save-dev babel-plugin-module-resolver babel-plugin-transform-object-rest-spread babel-plugin-transform-react-jsx-source babel-preset-expo
Babel-plugin-module-Resolutionver là một plugin giải quyết các module dự án của bạn khi biên dịch với Babel. Ta sẽ sử dụng gói này để đặt alias react-native thành react-native-web khi cài đặt cấu hình dự án.
Để xây dựng và chạy ứng dụng của ta , ta sẽ sử dụng Expo . Expo là một chuỗi công cụ open-souce được xây dựng xung quanh React Native để xây dựng các ứng dụng Android và iOS. Nó cung cấp quyền truy cập vào chức năng của hệ thống như Máy ảnh, Bộ nhớ, v.v.
Cài đặt module expo-cli
bằng cách chạy lệnh sau nếu bạn đang sử dụng Yarn:
- yarn global add expo-cli
Hoặc, nếu sử dụng npm
, hãy sử dụng lệnh này:
- npm i g expo-cli
Bước tiếp theo là cài đặt triển lãm local , cùng với React Native và React Native Web. Chạy lệnh sau để cài đặt các gói bằng Yarn:
- yarn add expo react-native react-native-web react-art
Hoặc, đối với npm
:
- npm i expo react-native react-native-web react-art
Sau khi download các gói cần thiết để chạy và xây dựng ứng dụng, bước tiếp theo là cài đặt các file cấu hình. Tạo một file có tên .babelrc
trong folder root của dự án của bạn:
- nano .bablerc
Thêm mã sau vào file để cấu hình bộ chuyển đổi mà dự án của bạn sẽ sử dụng:
{ "presets": ["babel-preset-expo"], "env": { "development": { "plugins": ["transform-object-rest-spread", "transform-react-jsx-source"] } }, "plugins": [ [ "module-resolver", { "alias": { "^react-native$": "react-native-web" } } ] ] }
Tạo một file có tên app.json
. Tệp này được sử dụng để cấu hình các phần ứng dụng của bạn không thuộc mã như name
ứng dụng, description
, sdkVersion
, v.v. Bạn có thể tìm thấy các tùy chọn có sẵn cho file app.json
tại đây .
- nano app.json
Trong file , hãy thêm mã này:
{ "expo": { "sdkVersion": "31.0.0", "name": "random-people", "slug": "random-people", "version": "0.1.0", "description": "An application for displaying random people", "primaryColor": "#ff8179" } }
Hãy cập nhật file package.json
để bao gồm các lệnh chạy ứng dụng của ta trên trình giả lập Android và iOS. Ngoài ra, ta sẽ bao gồm trường main
tham chiếu đến file App.js
Tệp này sẽ đóng role là file đầu vào cho hội nghị. Mở file package.json
trong editor :
- nano package.json
Sửa đổi file để file trông giống như sau:
// 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 android", "ios": "expo ios", "build:ios": "expo build:ios", "build:android": "expo build:android", }, ... }
Chạy npm run start-web
để chạy ứng dụng và truy cập http: // localhost: 3000 để xem ứng dụng.
Bước 2 - Tạo thành phần Home
Ứng dụng của ta là một bản demo đơn giản hiển thị user thông qua API user ngẫu nhiên . Sử dụng API, ta sẽ hiển thị tên và hình đại diện của những user đã trả lại thông qua một số thành phần được cung cấp bởi React Native. Trong folder src/
, tạo một file có tên home.js
- nano src/home.js
Thêm mã này vào file để xác định thành phần:
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;
Thành phần Home
hiển thị một thành phần ScrollView chứa các phần tử của thành phần đó. Hiện tại, thành phần hiển thị một ActivityIndicator ; điều này sẽ được thay thế bằng danh sách user khi lệnh gọi tới API hoàn tất.
Ta tạo kiểu cho các phần tử bằng cách sử dụng thành phần StyleSheet . Điều này cho phép ta tạo kiểu cho thành phần bằng cách sử dụng các thuộc tính tương tự như thuộc tính CSS.
Hãy tạo một phương thức lấy user ngẫu nhiên từ API user ngẫu nhiên. Phương thức này sẽ được gọi trong vòng đời componentDidMount
. Cập nhật thành phần home.js
để bao gồm phương thức getUsers
:
import React from 'react'; ... 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 }); } ... }
Ta có thể dễ dàng đưa ra yêu cầu bằng cách sử dụng API tìm nạp root . Kết quả từ yêu cầu được phân tích cú pháp và thêm vào trạng thái. Khi yêu cầu hoàn tất, ta sẽ ẩn ActivityIncidator
bằng cách đặt loading
thành false.
Bước 3 - Tạo thành phần ứng dụng
AppComponent
giữ logic cho ứng dụng. Ta sẽ cập nhật chế độ xem mặc định do Create React App tạo cho phù hợp với ứng dụng của ta bằng cách thêm logic để hiển thị các thành phần root .
Tạo một file mới có tên App.js
trong folder root của dự án của bạn.
- nano App.js
Tệp này sẽ tương tự như file src/App.js
App.js
root sẽ hoạt động như file mục nhập cho Expo và file src/App.js
tồn tại cho các bản dựng Ứng dụng Tạo React. Thêm mã này vào App.js
trong folder root của dự án của bạn:
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;
Trong đoạn mã trên, ta đăng ký thành phần Ứng dụng của bạn bằng AppRegistry. AppRegistry là điểm đầu vào của các ứng dụng React Native.
Bây giờ mở src/App.js
trong trình soạn thảo của bạn và thêm mã tương tự vào file đó.
Bây giờ chuyển sang tạo mục User .
Bước 4 - Tạo mục user
Mỗi mục user sẽ được hiển thị bằng cách sử dụng thành phần View
. Thành phần View là một khối xây dựng quan trọng hỗ trợ bố cục bằng cách sử dụng flexbox, tạo kiểu và khả năng truy cập. Thành phần Chế độ xem của mỗi mục sẽ nằm trong Danh sách có thể thay đổi. Mỗi mục sẽ hiển thị ảnh đại diện, tên và email của user . Tạo một file có tên user-item.js
trong folder src/
:
- nano src/user-item.js
Thêm mã sau vào file :
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;
Để hiển thị hình đại diện của mỗi user , ta sử dụng thành phần Hình ảnh . Thành phần này nhận một source
hỗ trợ hoạt động src
mà ta đã quen thuộc trên web. Thành phần có thể được tạo kiểu thêm khi ta sử dụng styles.rowIcon
tính styles.rowIcon
.
Tiếp theo, ta sẽ tạo UserList
để hiển thị từng UserItem
.
Bước 5 - Tạo danh sách user
Thành phần FlatList
là thành phần có hiệu suất cao trong các phương thức kết xuất danh sách của nó. Nó tải các mục trong danh sách và chỉ tải thêm các mục khác khi user đã cuộn đến cuối danh sách. SwipableFlatList là một shell bọc xung quanh FlatList do React Native Web cung cấp, giúp mỗi mục trong danh sách có thể swipe được - vì vậy mỗi mục sẽ hiển thị một tập hợp các hành động khi được swipe .
Hãy tạo SwipeableFlatList
cho những user được trả về từ API. Nhập thành phần SwipeableFlatList
từ gói SwipeableFlatList
react-native
và cập nhật chức năng kết xuất để hiển thị danh sách. Tạo một file có tên user-list.js
trong folder src
:
- nano src/user-list.js
Thêm mã này vào file :
import React from "react"; import { SwipeableFlatList } from "react-native"; import UserItem from "./user-item"; const UserList = ({ users }) => { return ( <SwipeableFlatList data={users} bounceFirstRowOnMount={true} maxSwipeDistance={160} renderItem={UserItem} /> ); }; export default UserList;
data
: phần hỗ trợ này đại diện cho dữ liệu sẽ được cung cấp cho từng mục trong danh sách. Chỗ dựadata
thường là một mảng.-
bounceFirstRowOnMount
: nếu đúng, nó kích hoạt hoạt ảnh trả lại trên mục đầu tiên trong danh sách, biểu thị rằng nó có các hành động ẩn bên trong. -
maxSwipeDistance
: giá đỡ này đặt khoảng cách có thể swipe tối đa cho mỗi mục. - Cuối cùng,
renderItem
prop nhận một chức năng hiển thị một mục; chức năng này sẽ được thông qua mộtitem
đỡitem
có chứa dữ liệu được hiển thị.
Hãy cập nhật các src/home.js
file bao gồm các mới UserList
. Mở file /src/home.js
và cập nhật file như sau:
import React from "react"; import { ScrollView, StyleSheet, ActivityIndicator } from "react-native"; import UserList from "./user-list"; class Home extends React.Component { state = { users: [], loading: true }; ... render() { return ( <ScrollView noSpacer={true} noScroll={true} style={styles.container}> {this.state.loading ? ( <ActivityIndicator style={[styles.centering]} color="#ff8179" size="large" /> ) : ( <UserList users={this.state.users} /> )} </ScrollView> ); } } const styles = StyleSheet.create({ ... }); export default Home;
Bây giờ nếu bạn truy cập http: // localhost: 3000 trên trình duyệt của bạn , bạn sẽ thấy danh sách user .
Ta đang sử dụng một SwipeableFlatList
thành phần nghĩa là mỗi mục dùng là swipeable, vì vậy ta hãy thêm hành động mà bạn có thể swipe sang tiết lộ.
Bước 6 - Thêm hành động vào mục
Mỗi mục trong danh sách sẽ được cung cấp một tập hợp các hành động sẽ được hiển thị khi swipe sang trái. Tập hợp các hành động sẽ sử dụng thành phần TouchableHighlight được bao bọc bởi thành phần View. Thành phần TouchableHighlight được sử dụng khi ta yêu cầu người xem phản hồi các thao tác chạm, ít nhiều hoạt động giống như một nút. Tạo một file có tên user-actions.js
trong folder src/
.
- nano src/user-actions.js
Thêm các nội dung sau vào file :
import React from "react"; import { View, TouchableHighlight, Text, Alert, StyleSheet } from "react-native"; 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" } }); 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> ); }; export default UserActions;
Thành phần TouchableHighlight nhận lệnh gọi lại onPress
được kích hoạt khi thành phần được nhấp. Mỗi lần gọi lại sẽ kích hoạt màn hình Alert
. Các kiểu cũng được áp dụng cho thành phần Chế độ xem bao trùm và các thành phần khác trên trang.
Bao gồm các hành động trên từng hạng mục sử dụng, cập nhật UserList
thành phần bao gồm các renderQuickActions
prop, mà cũng phải mất một hàm. Mở src/user-list.js
và sửa đổi nó:
import React from "react"; ... import UserActions from "./user-actions"; const UserList = ({ users }) => { return ( <SwipeableFlatList ... renderQuickActions={UserActions} /> ); }; export default UserList;
Bây giờ khi bạn swipe sang trái trên bất kỳ mục user nào, nó sẽ hiển thị hai hành động.
Bước 7 - Thêm thành phần tiêu đề
Bây giờ ta đã tìm nạp thành công user và hiển thị họ bằng cách sử dụng các thành phần root , hãy làm sống động ứng dụng bằng cách đặt tiêu đề. Sử dụng thành phần SafeAreaView, ta sẽ tạo một khu vực có ranh giới xác định. Điều này sẽ hoạt động như tiêu đề cho ứng dụng của ta . Tạo một file mới có tên là header.js
trong folder src/
:
- nano src/header.js
Thêm mã sau vào file :
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;
Bây giờ ta hãy thêm thành phần Header
thành phần App
. Thao tác này sẽ hiển thị một tiêu đề đơn giản ở đầu ứng dụng. Cập nhật file App.js
để bao gồm thành phần Header
:
import React from 'react'; ... import Header from './header'; class App extends React.Component { render() { return ( <View style={styles.appContainer}> <Header title="Random People" /> <Home /> </View> ); } } const styles = StyleSheet.create({ ... }); AppRegistry.registerComponent('App', () => App); export default App;
Sau khi ứng dụng làm mới, tiêu đề sẽ được thêm vào đầu ứng dụng.
Hãy nhớ sửa đổi file App.js
trong folder root của dự án của bạn với những thay đổi này, để nó hoạt động với Expo khi bạn kiểm tra.
Hãy xem các phương pháp khác nhau mà ta có thể sử dụng để kiểm tra ứng dụng trên thiết bị di động.
Bước 8 – Kiểm tra trên thiết bị di động
Tiện ích expo-cli
cung cấp nhiều phương pháp khác nhau để kiểm tra ứng dụng trên thiết bị di động. Đầu tiên là sử dụng URL được tạo sau khi chạy ứng dụng, URL này có thể được truy cập trên trình duyệt di động của bạn để kiểm tra ứng dụng.
Để kiểm tra ứng dụng trên thiết bị di động, hội expo-cli
cung cấp nhiều phương pháp khác nhau để kiểm tra ứng dụng trên thiết bị di động. Đầu tiên là sử dụng URL được tạo sau khi chạy ứng dụng. URL này có thể được truy cập trên trình duyệt di động của bạn để kiểm tra ứng dụng.
Chạy lệnh sau trong dự án của bạn để chạy ứng dụng với Expo:
- npm run start-native
Expo thường bắt đầu ứng dụng của bạn trên cổng 19002
, vì vậy hãy truy cập http: // localhost: 19002 để xem các công cụ dành cho nhà phát triển Expo. Trong các công cụ dành cho nhà phát triển, bạn có thể gửi một liên kết dưới dạng SMS hoặc email đến điện thoại di động của bạn .
Bạn có thể chọn bất kỳ tùy chọn kết nối nào trong ba tùy chọn kết nối - tunnel bên ngoài, mạng LAN hoặc kết nối local . Đối với kết nối local , điện thoại di động và máy tính phát triển của bạn phải được kết nối với cùng một mạng, nhưng tunnel hoạt động dù .
Tùy chọn tiếp theo để thử nghiệm trên thiết bị di động là sử dụng trình giả lập. Sử dụng Android studio hoặc Xcode , bạn có thể khởi động trình giả lập cho các nền tảng tương ứng của chúng. Download và cài đặt công cụ cho nền tảng bạn chọn - Xcode cho iOS hoặc Android studio cho Android. Sau khi cài đặt, chạy npm run android
hoặc npm run ios
để khởi động ứng dụng trên bất kỳ trình giả lập nào.
Bước 9 - Triển khai ứng dụng
Ta sẽ triển khai ứng dụng của bạn cho cửa hàng Android Play. Để làm điều này, ta cần cập nhật file app.json
để bao gồm các thuộc tính dành riêng cho Android . Mở file app.json
và cập nhật file để bao gồm trường android
:
{ "expo": { "sdkVersion": "31.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" } } }
Trường android.package
là một giá trị duy nhất sẽ đại diện cho gói của bạn trong cửa hàng ứng dụng. Bạn có thể đọc thêm về quy ước đặt tên gói tại đây . Sau khi cập nhật file , hãy chạy lệnh npm run build:android
.
Lệnh này sẽ hiển thị cho bạn một dấu nhắc , yêu cầu bạn cung cấp kho khóa hoặc tạo một kho khóa mới. Nếu bạn có một kho khóa hiện tại, bạn có thể chọn tùy chọn này hoặc để triển lãm tạo một kho khóa cho ứng dụng của bạn.
Sau khi hoàn thành, một liên kết download sẽ được tạo cho ứng dụng của bạn. Nhấp vào liên kết này sẽ kích hoạt download APK của bạn.
Để triển khai APK đã download tới Cửa hàng Play của Android, hãy truy cập Play Console để tạo account . Sau khi tạo account , bạn sẽ phải trả phí đăng ký 25 đô la trước khi tiếp tục. Sau khi hoàn tất quá trình đăng ký, hãy truy cập trang này và làm theo các bước để tải ứng dụng của bạn lên Cửa hàng Play.
Kết luận
Sử dụng thư viện React Native Web và React Native, bạn đã tạo một ứng dụng có thể được triển khai trên một số nền tảng bằng cách sử dụng các thành phần root . Việc xây dựng các ứng dụng đa nền tảng chưa bao giờ dễ dàng hơn thế. Bạn có thể xem mã nguồn của bản demo tại đây .
Các tin liên quan
Cách gọi API web với useEffect Hook trong React2020-10-05
Cách triển khai xác thực API bằng mã thông báo web JSON và hộ chiếu
2020-09-24
Cách cài đặt và sử dụng GoAccess Web Log Analyzer trên Ubuntu 20.04
2020-09-15
Xây dựng ứng dụng web CRUD với Python và Flask - Phần thứ nhất
2020-09-15
Phông chữ có thể thay đổi trên web bằng CSS
2020-09-01
Làm thế nào để tạo một Web Scraper đồng thời với Puppeteer, Node.js, Docker và Kubernetes
2020-08-19
Cách tạo ứng dụng web tiến bộ với Angular
2020-07-09
Cách cài đặt Django Web Framework trên Ubuntu 20.04
2020-07-06
Cách tạo chế độ xem để phát triển web Django
2020-05-14
Cách tạo chế độ xem để phát triển web Django
2020-05-14