React native lỗi không kết nối được máy ảo năm 2024
Chào mừng các bạn đến với hướng dẫn học React-Native cho người mới bắt. Sau đây là một số chia sẻ, hướng dẫn của mình cho người mới bắt đầu tìm hiểu về React-Native. Qua đó nhằm giúp các bạn có cách nhìn tổng quát hơn và dễ dàng tìm hiểu vấn đề khi mới chập chững bước chân vào lập trình với React-Native. Show
P/s: Bài viết chủ yếu dựa trên tài liệu chính thống của React-Native phiên bản 0.56 tại https://facebook.github.io/react-native/docs/getting-started kết hợp với sự hiểu biết cá nhân của mình vì vậy nếu có sai sót, anh em cứ góp ý để mình sửa đổi nhé. Mục Lục
I. Mục tiêu hướng dẫn
II. Một vài lưu ý
Khuyến nghị: Sau những lần tìm hiểu và phát triển ứng dụng thì mình khuyến cáo không nên sử dụng Expo (framework của react) để phát triển ứng dụng đơn giản. Bởi vì dự án của bạn sẽ nặng lên, bạn rất khó quản lý permission và các thư viện đi kèm. III. NỘI DUNG HƯỚNG DẪN1. Hướng dẫn cài đặt môi trường react-native trên hệ điều hành Windows.
Lưu ý: Trên hệ điều hành windows chỉ có thể build ứng dụng trên Android. 2. Hướng dẫn cài đặt môi trường react-native trên hệ điều hành MAC OS
3. Các IDE khuyên dùng
P/s: Nếu sử dụng MAC thì nên dùng Xcode để chạy ứng dụng. Bởi vì một số lý do như: Run các lần sau nhanh hơn, xem log debug mà không cần bật chức năng Debug JS Remotely và quan trọng là làm quen với một số chức năng của Xcode để lúc xảy ra lỗi fix lỗi nhanh hơn. Với Android thì có một vài trở ngại khi dùng Android studio như việc run mà không dùng code react-native mới nhất, chức năng host reloading cũng khó hoạt động. 4. Khởi tạo dự án đầu tiên
Khi chạy lệnh này hệ điều hành sẽ tạo một server local để build code react của bạn. Kèm theo đó là chạy các lệnh để build ứng dụng. Bạn cũng có thể mở file /ios/ProjectName.xcodeproj bằng Xcode để khởi chạy ứng dụng, hoặc mở nguyên thư mục android bằng Android studio để khởi chạy ứng dụng.
Chú ý version phiên bản glog (0.3.5) mà bạn đang sử dụng. 5. Các thành phần cơ bản của dự ánCấu trúc thư mục mà bạn nhìn thấy có thể sẽ như dưới đây (tùy version react-native hiện tại của bạn). Hình dưới đây không bao gồm một vài file bị ẩn thuộc cấu hình của react-native
6. Component trong React-NativeComponent là một thành phần cơ bản trong ứng dụng react-native. Mọi view, screen đều được kế thừa từ lớp component này. 6.1. Vòng đời của component(Nguồn:: internet)Các hàm được gọi trong vòng đời của Component
6.2. Các thành phần cơ bản của componentSau đây là chương trình mẫu cơ bản để ta hiểu được các thành phần của một Component import React, { Component } from 'react'; import { Text, View } from 'react-native'; export default class App extends Component { }
import React, { Component } from 'react'; import { Text, View } from 'react-native'; class CustomText extends Component { }
export default class App extends Component { }6.3. Một số hàm đặc biệt
this.setState({ message: "Chào mừng", key: "Value", }) console.log(this.state.message) //không nên // không sử dụng this.state ngay sau khi vừa set xong // biến truyền vào cho hàm setState là một đối tượng có dạng key: value. Có thể sử dụng callback để check dữ liệu hoặc xử lý một số tác vụ sau khi thay đổi trạng thái this.setState({ message: "Chào mừng" }, ()=>{ console.log(this.state.message) // kết quả: Chào mừng })
6.4. Một vài lưu ý nhỏ khi dùng React-Native
7. Thiết kế View (Style)Sau đây là một đoạn code Demo về Style của ứng dụng React-Native. Code có sẵn trong Example (Example/app/modules/screens/Home/StyleDemo) export class StyleDemo extends React.Component { }
const styles = StyleSheet.create({ });Giống như một ứng dụng web cơ bản, React-Native sử dụng một số thẻ css để vẽ những gì bạn muốn. Nếu bạn là lập trình web quen thuộc với css thì việc thiết kế này khá đơn giản. Để trau dồi những khả năng này chỉ có cách là làm nhiều bạn sẽ tìm hiểu những style bạn muốn và sẽ làm ứng dụng của bạn đẹp hơn. Ở ví dụ trên bạn có thể thay đổi các thuộc tính của style rồi reload lại để thấy sự thay đổi nhé. Trong ví dụ thư mục Home tôi đã chia phần Style qua một file khác để dễ quản lý (Từ các ví dụ sau trở đi, tôi sẽ chia phần style này sang 1 file khác để dễ quản lý). Bạn có thể vào đó, thử thay đổi, xóa sửa để biết được thuộc tính nào dùng để làm gì nhé. Làm nhiều phần này thì sẽ có kinh nghiệm thiết kế đẹp thôi. Một vài lưu ý:
8. Kỹ thuật Debug cơ bảnXây dựng ứng dụng React-Native khác với ứng dụng native là bạn không thể đặt break point rồi chạy và chờ chương trình nhảy vào vị trí mà bạn đợi và xem trạng thái hay biến lúc đó bằng bao nhiêu đang như thế nào. Thay vì vậy chương trình React-Native cho phép bạn in giá trị tại thời điểm đó và xuất ra màn hình console. Sử dụng lệnh this.setState({ message: "Chào mừng" }, ()=>{ console.log(this.state.message) // kết quả: Chào mừng }) 3 để in giá trị của biến bất kì (xem ví dụ phía trên để biết việc in giá trị của biến message trong state) Xcode và Android studio mặc định khi run debug sẽ xuất các log này ra trong phần All Output (Xcode), Logcat (Android Studio). Bên cạnh đó bạn có thể sử dụng chức năng Debug JS Remotely (xem phần hiển thị menu điều khiển trong mục 4) để thấy các log này trong phần console của trình duyệt web. Ngoài ra bạn có thể sử dụng terminal (cmd) để xem log IOS hoặc Android bằng cách gõ lệnh:
9. Các Component thường sử dụngDưới đây là code demo những component cơ bản thường sử dụng. Bạn có thể code lại, copy hoặc chạy demo từ example (demo có sử dụng hình ảnh nên bạn phải copy hình ảnh trong example - Example/app/assets/images). import React from 'react'; import { Image, View, Text, Button, TouchableOpacity, FlatList, StyleSheet } from 'react-native'; import { Colors } from '../../../configs/style'; export class Components extends React.Component { //Header ứng dụng (tùy chọn) # 841584" }
//Trong example mình tách phần Styles này qua file khác cho dễ đọc
const Styles = StyleSheet.create({ });Sau khi chạy Demo ta được UI như sau (run example thì click vào component) 9.1. ViewLà một component cũng thường xuyên được sử dụng. Thường được sử dụng với mục đích chia các view con theo hàng dọc hoặc hàng ngang dựa vào thuộc tính flexDirection trong style là 'column/row' (dọc / ngang), hoặc sử dụng để chứa nhiều view con hoặc khi cần in ra màn hình một view không hiển thị gì hết ví dụ như trong cấu trúc toán tử:
flex: 1 ở style sẽ giúp kéo view rộng hết khung chứa có thể. 9.2. TextDùng để hiển thị 1 message lên màn hình. Có thể sử dụng text cố định hoặc in nội dung của một biến lên màn hình
0 9.3. ImageDùng để hiển thị hình ảnh lên màn hình. Có 3 cách hiển thị:
1
2
3 Resize Mode quen thuộc:
9.4. ButtonCách sử dụng một Button
4 Thông thường mình ít khi sử dụng Button vì lý do custom style nó không hoạt động đúng với cả Android và IOS vì vậy nên mình thường sử dụng TouchableOpacity hơn. Nhưng lưu ý cách sử dụng sự kiện onPress this.setState({ message: "Chào mừng" }, ()=>{ console.log(this.state.message) // kết quả: Chào mừng }) 4 Vui lòng viết theo cấu trúc này để giảm thiểu lỗi hoặc là phải binding hàm trong contrucstor trước lúc sử dụng. Sự kiện onPress chỉ có một số component hỗ trợ, Text thì không hỗ trợ nên nếu muốn sử dụng onPress cho Text thì đọc phần TouchableOpacity phía dưới nhé. 9.5. TouchableOpacityThông thường mình thay thế việc sử dụng Button bằng TouchableOpacity để việc định dạng style giống nhau cho cả android và ios, TouchableOpacity có thể chứa bất kỳ view con nào, và nhớ lưu ý cách dùng sự kiện onPress giống như Button nhé.
5 9.6. FlatlistĐây là Component thường được sử dụng để hiển thị 1 danh sách lên màn hình. Cách dùng:
6 Một vài lưu ý khi sử dụng Flatlist:
Các component ở trên mình chỉ mang tính chất giới thiệu để các bạn tìm hiểu. Để hiểu rõ hơn cũng như tìm hiểu thêm về các thuộc tính của mỗi component thì vui lòng đọc riêng tài liệu của các Component nhé. Mỗi component sẽ có nhiều thuộc tính khác để hỗ trợ bạn làm UI tốt và mượt nhất có thể. 10. Prop và cách truyền dữ liệu giữa các View (Screen)Tạo file App.js như sau
7 và 1 file ViewItem.js nằm cùng thư mục
8 Trong Example mình đã gộp style lại và đưa nó ra 1 file riêng là styles.js để dễ quản lý (demo trên có sử dụng hình ảnh nên bạn phải copy hình ảnh trong example - Example/app/assets/images). Ở ví dụ trên ta demo việc truyền dữ liệu giữa 2 component thông qua props Bên gửi qua (ViewItem đóng vai trò là 1 component được tùy biến)
9 Bên nhận dữ liệu có thể sử dụng dữ liệu được truyền qua thông qua props. (Kiểu nó ném mấy cái dữ liệu qua thì bên nhận này truy xuất thông qua props) import React, { Component } from 'react'; import { Text, View } from 'react-native'; export default class App extends Component { }0 Việc truyền dữ liệu ngược lại cũng được thể hiện trong ví dụ thông qua việc xử lý sự kiện onPressItem() import React, { Component } from 'react'; import { Text, View } from 'react-native'; export default class App extends Component { }1 Một vài lưu ý khi sử dụng props
11. Cài đặt và sử dụng thư viện11.1. Cài đặt thư việnThông thường trong React-Native sử dụng thư viện rất nhiều có lẽ vì một vài lý do:
Khi bạn gặp vấn đề hoặc cần làm một cái gì đó với react-native hãy tìm Google với từ khóa react-native + cái gì bạn muốn làm. Ví dụ muốn làm chức năng đăng nhập với facebook thì có thể tìm: react-native login with facebook. Đa phần bạn sẽ thấy thư viện hỗ trợ nằm ngay trang đầu tiên. Hãy vào trang chính thống của thư viện để xem cách cài đặt và sử dụng thư viện. Nhớ xem lại số star và các vấn đề trước khi bạn muốn sử một thư viện nào đó trên github. Nếu thư viện được publish trên npmjs https://www.npmjs.com/ thì bạn có thể cài đặt thông qua this.setState({ message: "Chào mừng" }, ()=>{ console.log(this.state.message) // kết quả: Chào mừng }) 6 11.2. Link thư việnMột phần khá quan trọng, sau khi bạn kéo thư viện từ npm về, thì bạn cần link thư viện đó vào app của bạn để ứng dụng có thể khởi chạy các phần code native của thư viện hoặc được quyền chạy một số tác vụ khác. Thông thường các thư viện đều có link tự động qua lệnh this.setState({ message: "Chào mừng" }, ()=>{ console.log(this.state.message) // kết quả: Chào mừng }) 7. Tùy vào từng thư viện sẽ có hướng dẫn và cách link bổ sung. Bên cạnh đó một số thư viện không link tự động được hoặc project của bạn có vấn đề phải link bằng tay lúc đó bạn nên tham khảo bài viết này trước để biết cách link và hiểu sâu hơn https://facebook.github.io/react-native/docs/linking-libraries-ios 11.3. Chỉnh sửa thư việnĐa phần trình quản lý source code (git/svn) sẽ không commit các thư viện có sẵn được cài đặt từ npm (thư mục node_modules) hoặc nếu mình cố gắng commit sẽ làm dự án của chúng ta nặng lên rất nhiều lần. Do vậy chúng ta không sửa trực tiếp thư viện trong node_modules. Sau khi cài đặt và link thư viện. Bạn hãy copy nguyên source code của thư viện qua app/modules và tiến hành sửa đổi, tùy biến thư viện tại đây. Lúc sử dụng nhớ chuyển đổi đường dẫn import thư viện qua dự án của bạn. Nếu đó là phần chỉnh sửa quan trong hy vọng bạn sẽ đóng góp cho cộng đồng bằng cách report lên dự án chính hoặc chia sẻ lại cho mọi người. 12. Chuyển đổi giữa các màn hìnhMột ứng dụng bạn phát triển không thể chỉ có một màn hình. Vì vậy bạn phải biết cách chuyển đổi qua lại giữa các màn hình. Hiện tại mình sử dụng thư viện react-navigation (v.2.18.1) để chuyển đổi giữa các màn hình. Các bạn có thể tìm hiểu thêm về thư viện này tại (https://reactnavigation.org)
- Xây dựng cấu trúc ứng dụng: Để bạn hiểu rõ hơn về phần demo sau bạn vui lòng xem lại file index.js trong Example (Example/app/index.js). Dưới đây là phần tạo cấu trúc sườn của ứng dụng dựa vào StackNavigator của thư viện react-navigation. import React, { Component } from 'react'; import { Text, View } from 'react-native'; export default class App extends Component { }2 Như bạn thấy ở trên ta khai báo 1 ứng dụng có 4 màn hình HOME, STYLES, COMPONENT, PROPS. Mặc định màn hình nào ở trên cùng sẽ được xuất hiện đầu tiên. Nội dung mỗi màn hình có dạng: import React, { Component } from 'react'; import { Text, View } from 'react-native'; export default class App extends Component { }3 Trong đó Screens.Home là class được import từ module screens. Lưu ý dòng lệnh: this.setState({ message: "Chào mừng" }, ()=>{ console.log(this.state.message) // kết quả: Chào mừng }) 9 Dòng lệnh này thực hiện import toàn bộ những class được xuất ra thông qua file index.js. Vì vậy nếu bạn thêm màn hình mới lưu ý vào file index.js để xuất thêm class bạn vừa tạo. - Chuyển đổi màn hình: có 2 cách chuyển màn hình:
13. Giao tiếp Client vs Server13.1. RESTful API.(nguồn internet)Nếu bạn không biết RESTful API là gì thì có thể đọc thêm bài viết này (https://viblo.asia/p/thiet-ke-restful-api-GrLZD98Vlk0) để hiểu rõ hơn về RESTful API. Đây là một trong những chuẩn giao tiếp phổ biến giữa client và server. Phần Demo này được trình bày khá rõ ràng và chi tiết trong ví dụ Example (app/modules/screens/RestFul/RestFul.js). Bạn nên chạy ví dụ trước để thấy cách hoạt động của nó. Demo bao gồm việc gọi một public api từ https://api.ice5.skyx.app/get_languages (GET) và hiển thị kết quả như sau:
import React, { Component } from 'react'; import { Text, View } from 'react-native'; export default class App extends Component { }7 Ở đây mình định nghĩa 1 lớp để quản lý việc trao đổi, giao tiếp giữa client và server. Hàm fetchData() là một hàm bất đồng bộ hỗ trợ gọi các phương thức RESTful. Và đây là cách chúng ta gọi hàm fetchData() và định nghĩa rõ ràng 1 api truy cập để lấy danh sách ngôn ngữ. Lưu ý: Thay vì việc mình đặt trực tiếp link https://api.ice5.skyx.app/get_languages thì mình lại gọi hàm getBaseURL() là để sau này có thay api, thì mình không phải đi thay nhiều chỗ, chỉ cần vào config và thay đổi là hoàn tất. import React, { Component } from 'react'; import { Text, View } from 'react-native'; export default class App extends Component { }8 Ví dụ gọi fetchData() với phương thức POST import React, { Component } from 'react'; import { Text, View } from 'react-native'; export default class App extends Component { }9
import React, { Component } from 'react'; import { Text, View } from 'react-native'; class CustomText extends Component { }
export default class App extends Component { }0 Lưu ý: Phương thức getLanguagesFromServer() nên gọi trong componentDidMount() hoặc các sự kiện sau khi constructor() hoàn tất để trách những lỗi có nguy cơ tiềm ẩn ví dụ như api nhanh quá, contrucstor chạy chưa xong và nó đi setState() thì app của bạn nó làm việc không đúng. 13.2. WebsocketComming soon 14. Lưu trữ dữ liệuReact-Native mặc định hỗ trợ chức năng lưu trữ thông qua AsyncStorage được cung cấp mặc định trong gói thư viện react-native. Xem phần Storage phía dưới để tìm hiểu thêm về phương pháp lưu trữ này. Bên cạnh đó mình xin được giới thiệu phương pháp lưu trữ theo dạng dữ liệu có cấu trúc sử dụng realm database. Theo bản thân mình realm được đánh giá là một trong những thư viện hỗ trợ database tốt và tối ưu cho dân lập trình trên các dòng mobile hiện tại. 14.1. AsyncStorage:Bởi vì AsyncStorage chạy bất đồng bộ vì vậy mình chỉ sử dụng AsyncStorage để lưu một số config của ứng dụng ví dụ như user data hay language code ..., những dữ liệu quan trọng và có cấu trúc thường mình sẽ sử dụng database để lưu trữ, truy xuất nhanh và dễ dàng hơn. import thư viện AsyncStorage: import React, { Component } from 'react'; import { Text, View } from 'react-native'; class CustomText extends Component { }
export default class App extends Component { }1 Sử dụng thư viện: import React, { Component } from 'react'; import { Text, View } from 'react-native'; class CustomText extends Component { }
export default class App extends Component { }2 14.2. Database:Thông thường mình sẽ dùng realm để lưu trữ các dữ liệu có cấu trúc. Mình xin demo nhỏ về một phần mềm quản lý, chỉnh sửa danh sách sinh viên: 15. Đa Ngôn ngữ16. Giao tiếp với Native17. Quy chuẩn tên biến và cấu trúc chương trìnhKhi bạn tìm hiểu được kha khá các vấn đề về React-Native và code được một vài chương trình đơn giản thì cũng là lúc chúng ta nên xem lại các quy chuẩn thiết kế, cũng như quy chuẩn về tên biến để:
Mình xin dưa ra một số quy chuẩn cơ bản như sau: 17.1. Tên biến và hàm:
17.2. Cấu trúc chương trình:Sau những dự án và tìm hiểu trên mạng. Mình có đưa ra mô hình cấu trúc thư mục dự án như sau !(images/project-structure.jpg) Toàn bộ source code của chương trình sẽ được đặt trong thư mục app:
models là thư mục chứa các model do mình định nghĩa, có thể là định nghĩa các đối tượng hoặc các loại của đối tượng |