Chào các bạn, để tiếp nối với phần 1 - React là gì và tại sao nó lại quan trọng? mình sẽ viết tiếp phần 2 về React Native.
GIỚI THIỆU
React Native hiểu đơn giản chính là React cùng với native component.
Được Facebook release ra vào năm 2015, React Native cho phép bạn tạo các ứng dụng di động chỉ với Javascript và React. React Native có kiến trúc thiết kế tương tự như React, cho phép bạn thiết kế, tái sử dụng các UI phong phú từ các component mặc định và các component đến từ đóng góp của người dùng.
React Native dù chỉ mới ra đời 2 năm, nhưng đã nhận được sự quan tâm không kém cạnh gì đàn anh React. Tại Github repo, React Native nhận được hơn 48k stars, cùng với 1316 contributors – thậm chí còn nhiều hơn React. Hiện nay, ở các diễn đàn công nghệ, conference, Mobile summit, Facebook group thì React Native luôn là chủ đề nóng bỏng được đưa ra thảo luận và dần trở thành một xu thế công nghệ.
VẤN ĐỀ & GIẢI PHÁP
Hiện nay theo sự phát triển của xã hội, nhu cầu tạo ra một ứng dụng mobiles và ứng dụng web đồng nhất và nhanh nhất ngày càng tăng. Tuy nhiên do rào cản nền tảng và mong muốn đó chưa được thực hiện.
Thời gian gần đây xuất hiện nhiều framework cho phép sử dụng các ngôn ngữ chạy trên web để phát triển ứng dụng mobile hay còn gọi là cross-platform development như PhoneGap, Ionic, Cordova,.. tuy nhiên ứng dụng tạo ra chỉ đạt đến mức hybrid-app, sử dụng các Webviews để hiển thị giao diện lên chứ không thực sự là native.
Việc sử dụng các ứng dụng hybrid làm giảm hiệu năng và không tối ưu trong việc xử lý.
Google cũng công bố cho mình một hướng tiếp cận khác, hoàn toàn bỏ đi native app mà sử dụng Progressive Web App (PWA), tuy hiệu năng khá tốt, nhưng vẫn không thể nào so sánh được với native app khi ứng dụng trở nên lớn hơn, mặt khác PWA được cho là khó giữ lại người dùng hơn là native app.
React Native cung cấp cho bạn một thứ hoàn toàn khác biệt, ứng dụng được tạo ra sẽ hoàn toàn native với hiệu năng cao, chứ không phải là “mobile web app”, “HTML5 app” hay “hybrid app”. Bạn có thể build một ứng dụng mobile mà khó có thể phân biệt được nó với các native app khác tạo hoàn toàn bằng Java hay Swift/Objective-C. React Native sử dụng các UI hoàn toàn giống với iOS hay Android app thông thường, điều đặc biệt là nó được xây dựng dễ dàng hơn thông qua Javascript và React.
TẠI SAO PHẢI SỬ DỤNG REACT NATIVE?
React Native trở nên phổ biến như vậy là vì nó ăn theo đàn anh React vốn đang làm mưa làm gió trong lĩnh vực CNTT?
Không!
React Native không có: Controllers, Derectives, Templates, Global Event Listener, Models, View-Models,.. Vậy tại sao lại chọn React Native mà không phải các framework khác?
Bởi vì React Native có Component.
React Native trở nên phổ biến như vậy là vì nó ăn theo đàn anh React vốn đang làm mưa làm gió trong lĩnh vực CNTT?
Không!
React Native không có: Controllers, Derectives, Templates, Global Event Listener, Models, View-Models,.. Vậy tại sao lại chọn React Native mà không phải các framework khác?
Bởi vì React Native có Component.
Component của React Native được kế thừa từ React, và nó đóng vai trò như hạt nhân thúc đẩy React và React Native phát triển, với khả năng tái sử dụng và quản lý giao diện, Component API được xem như là tương lai của thiết kế UI trên web và mobile.
- Thực sự native
- Learn once write anywhere
Bởi vì Facebook nhận ra rằng với mỗi nền tảng khác nhau sẽ có mỗi giao diện, cảm nhận, khả năng khác nhau nên React Native vẫn hướng đến phát triển những ứng dụng riêng biệt cho từng platform để đem lại trải nghiệm tốt nhất cho người dùng.
Ở cấu trúc bên dưới, Js code chạy ở một thread riêng biệt với UI thread, vì vậy dù app có chạy với logic phức tạp đến mức nào thì UI vẫn cực kì mượt và không bị block bởi Js worker thread.
Kết quả hiện ra trên máy ảo như sau:
Rất nhiều tính năng nổi bật của ES6 như:
- Thay vì sử dụng var để khi báo biến cục bộ, ES6 sử dụng const và let,
- Khai báo annonymous function bằng fat arrow (=>)
- Chia source code ra thành nhiều module và sử dụng cú pháp import/export để quản lý.
- Đăt giá trị mặc định cho tham số của hàm
- …
Một điều kì lạ trong file index.ios.js demo ở trên là phần <Text>Hello world!</Text>. Như đã giải thích ở bài trước, đó là cú pháp của JSX, một cú pháp dành cho việc nhúng tag-based XML vào Javascript để sử dụng. Mỗi tag như sẽ được chuyển đổi thành một lần gọi hàm để tạo các component/element.
d. React component.
Component như đã nói ở trên, chính là cốt lõi của React, React Native, và là tương lai của công nghệ. React Native cho phép chúng ta xây dựng các Native UI Component đại diện cho các block của UI, và nhận nhiệm vụ mapping từ Js components sang native UI và render ra màn hình
Cả giao diện màn hình của thiết bị được vẽ như thế nào, bao gồm cả StatusBar, NavigationBar đều được qui định bởi các React Component. Thứ tự của các components trong cấu trúc cây của JSX cũng là thứ tự khi vẽ lên màn hình.
Các React Component không thể tự thay đổi props của chính nó được, mà phải nhờ một component cha thiết lập thuộc tính cho nó, và giá trị đó sẽ cố định trong suốt vòng đời của component đó. Đối với các thuộc tính thường xuyên thay đổi hoặc muốn thay đổi trong nội tại component ta cần sử dụng một khái niệm khác, gọi là state.
Với State, ta có thể maintain trạng thái và các thuộc tính của nó ngay trong nội tại component. State cũng có thể truy cập trong nội tại của component, tuy nhiên không như props, các component cha có thể không truy cập được vào state của component con.
Về tổng quát, bạn nên khởi tạo state ngay trong constructor của component, sau đó sử dụng hàm this.setState(object newState) để gán trạng thái cho component bất cứ khi nào bạn muốn. Và lưu ý rằng không nên truy cập và thay đổi trực tiếp bất cứ thuộc tính nào của state bằng cách gọi this.state.foo = ‘bar’, mà phải thực hiện thông qua hàm this.setState(‘bar’).
g. Style
Với React Native, bạn không cần dùng thêm một ngôn ngữ nào (như CSS) để qui định style cho các component khi vẽ lên màn hình. Tất cả những thứ bạn cần là sử dụng Javascript để tạo ra các object chứa các giá trị cần cho style.
h. Networking
Nhiều mobile apps cần phải load tài nguyên từ remote URL. Bạn cần phải tạo các POST request đến các REST API, và tải dữ liệu về thông qua GET request. Hoặc đơn giản bạn chỉ cần fetch các dữ liệu tĩnh ở đâu đó trên Internet về (Vd: tải một hình ảnh tĩnh,..).
Networking trong React Native được tạo ra từ hai API chính: Fetch và XMLHttpRequest. Cả hai đều được thiết kế để tương thích với API của trình duyệt, vì vậy:
- Lập trình viên Web không cần phải học một cách mới để tạo các network requests.
- Các thư viện đều được xây dựng trên nền tảng của 2 API trên cho React Native.
Ví dụ: Tải một content từ trang web tĩnh: fetch('https://iceteaviet.blogspot.com/hcmus.json')
Fetch cũng có thể thêm các tham số optional để customize HTTP request của bạn. Bạn có thể định rõ ra các header khi gửi POST request.
Bạn có thể tham khảo rõ hơn các ví dụ về Fetch API và các custom libraries khác tại đây hoặc đây.
i. Tích hợp React Native vào một ứng dụng có sẵn.
React Native rất tốt nếu bạn bắt đầu tạo ứng dụng với nó ngay từ đầu. Tuy nhiên đối với các project lớn nó cũng cực kì tốt khi thêm một vài SingleView hoặc user flow vào một dự án native có sẵn chỉ với một vài bước.
Bạn có thể tham khảo thêm tại đây hoặc bài blog sau.
Chúc các bạn học tốt và đừng quên để lại bình luận bên dưới nhé.
React Native đi theo một mục đích là học một lần những cốt lõi của ReactJs, và sau đó áp dụng nó vào tất cả các project từ web app đến mobile app (Android, iOS) mà không cần học thêm một công nghệ khác nào – Learn once, write everywhere.
Với tư duy và nền tảng có được khi học React bạn có thể dễ dàng chuyển đổi giữa việc lập trình Web và lập trình ứng dụng mobile, đáp ứng công việc thực tế.
- Live reloading – Hot reloading
Điều này sẽ đẩy mạnh quá trình phát triển app và các máy tính yếu sẽ không còn gặp vấn đề build lại project nhiều lần, tốn thời gian chờ đợi và ảnh hưởng hiệu năng máy tính như khi lập trình Android/iOS bình thường.
- Dễ dàng kết hợp với native code (Java, Swift,..)
- Hiệu năng cao
Ở cấu trúc bên dưới, Js code chạy ở một thread riêng biệt với UI thread, vì vậy dù app có chạy với logic phức tạp đến mức nào thì UI vẫn cực kì mượt và không bị block bởi Js worker thread.
- Dễ học
React Native cũng là chủ đề nóng bỏng được thảo luận và đăng tải thường xuyên, số lượng câu hỏi, tutorial, blog về React Native cũng đang tăng với số lượng chóng mặt, vì vậy thật dễ dàng để học hay tìm ra câu trả lời cho vấn đề bạn đang mắc phải.
SỬ DỤNG NHƯ THẾ NÀO?
Với chủ đề là React và Swift, mình xin hướng dẫn các bạn một số vấn đề với React Native và iOS development.
Với chủ đề là React và Swift, mình xin hướng dẫn các bạn một số vấn đề với React Native và iOS development.
a. Getting started.
Để có thể sử dụng React Native cho iOS bạn cần phải có một máy tính cài đặt hệ điều hành MacOSX (có thể là máy ảo, hoặc máy Hackintosh).
Tiến hành cài đặt các dependencies cần thiết như NodeJS và Watchman sử dụng Homebrew bằng cách chạy các dòng lệnh sau:
$ brew install node
$ brew install watchman
$ brew install watchman
Tiếp theo, cài đặt React Native CLI (command line interface):
npm install -g react-native-cli
Cài đặt XCode thông qua Mac App Store. Nên cài Xcode phiên bản 8.0 hoặc cao hơn để đảm bảo tương thích với các tính năng mới của các bản release React Native gần đây.
Kiểm tra lại việc cài đặt bằng cách tạo và chạy thử một project:
react-native init AwesomeProject
cd AwesomeProject
react-native run-ios
cd AwesomeProject
react-native run-ios
Kết quả hiện ra trên máy ảo như sau:
Dòng lệnh chỉ là một cách để chạy ứng dụng của bạn. Ngoài ra bạn còn có thể chạy bằng cách nhấn trực tiếp phím Run trong Xcode hoặc trong Nuclide.
Thử thay đổi một vài giá trị trên giao diện bằng cách:
- Mở file index.ios.js (hoặc index.android.js cho Android) bằng text editor và thử sửa dòng "Welcome to React Native!" thành tên của bạn.
- Chọn trở lại máy ảo Simulator khi nãy và ấn tổ hợp phím Command⌘ + R để thực hiện Live reload và cập nhật thay đổi lên ứng dụng.
Vậy là bạn đã thành công trong việc tạo và chỉnh sửa một app React Native đầu tay cho mình rồi.
b. Javascript “mới”
Hãy cùng mở lại file index.ios.js khi nãy và xem kĩ lại:
Hãy cùng mở lại file index.ios.js khi nãy và xem kĩ lại:
Có gì đó kì lạ ở đây, một cái gì đó không thực sự giống như Javascript???
Đừng hoang mang, đây là tương lai!
Đầu tiên ES2015 (hay ECMAScript6, ES6) là một bộ cải thiện Javascript mà hiện nay đã trở thành chuẩn chung cho các lập trình viên. Nhiều tính năng của ES6 đã sẵn sàng cho các engine Js hiện đại. Bằng cách sử dụng Babel, chúng ta có thể đảm bảo các tính năng của ES6 có thể chạy trên nhiều nền tảng khác nhau (Android, iOS, Windows,...)
Rất nhiều tính năng nổi bật của ES6 như:
- Thay vì sử dụng var để khi báo biến cục bộ, ES6 sử dụng const và let,
- Khai báo annonymous function bằng fat arrow (=>)
- Chia source code ra thành nhiều module và sử dụng cú pháp import/export để quản lý.
- Đăt giá trị mặc định cho tham số của hàm
- …
Và quan trong hơn hết, ES6 bắt đầu có khái niệm JS classes. Trước đó “class” trong Js thực chất chỉ là các function với instance method được gán vào MyFunction.prototype.
ES6 cho phép ta sử dụng cú pháp đơn giản hơn với chỉ một từ khóa class. Class trong ES6 cho phép ta sử dụng các hàm có sẳn, viết thêm hàm, kế thừa và có cả constructor như class của các ngôn ngữ khác.
c. JSX
Một điều kì lạ trong file index.ios.js demo ở trên là phần <Text>Hello world!</Text>. Như đã giải thích ở bài trước, đó là cú pháp của JSX, một cú pháp dành cho việc nhúng tag-based XML vào Javascript để sử dụng. Mỗi tag như sẽ được chuyển đổi thành một lần gọi hàm để tạo các component/element.
JSX giúp cho việc thiết kế giao diện trở nên dễ dàng hơn, dễ đọc hiểu và tưởng tượng ra được mình đang thiết kế UI gì.
Bạn không bắt buộc phải sử dụng JSX, tuy nhiên cách áp dụng này không có khuyết điểm nào và thực sự nên dùng.
d. React component.
Component như đã nói ở trên, chính là cốt lõi của React, React Native, và là tương lai của công nghệ. React Native cho phép chúng ta xây dựng các Native UI Component đại diện cho các block của UI, và nhận nhiệm vụ mapping từ Js components sang native UI và render ra màn hình
Cả giao diện màn hình của thiết bị được vẽ như thế nào, bao gồm cả StatusBar, NavigationBar đều được qui định bởi các React Component. Thứ tự của các components trong cấu trúc cây của JSX cũng là thứ tự khi vẽ lên màn hình.
React Native hỗ trợ sẵn khá nhiều components tương ứng với các View cơ bản của iOS/Android. Danh sách có thể được xem tại đây.
Ngoài ra các React Component còn có thể tái sử dụng qua lại giữa Web và Mobile làm cho việc thống nhất hóa các trang web và ứng dụng của một công ty trở nên dễ dàng hơn bao giờ hết
e. Props
Nhiều component có thể được customize khi nó được tạo ra bằng nhiều thuộc tính khác nhau, những thuộc tính/tham số đó gọi là props.
Props có thể được hiểu như properties của một component, tất cả các component đều có thể có props dù đó là component cơ bản của React Native hay custom component do người dùng tạo ra. Props có thể được truy cập nội tại bên trong component, cho phép component đó biết nó phải hoạt động như thế nào, hiển thị thế nào lên màn hình.
Ví dụ với một component cơ bản của React Native là <Image>. Khi ta tạo một Image ta có thể sử dụng một props tên là “source” để kiểm soát cái gì sẽ được in ra màn hình.
Các React Component không thể tự thay đổi props của chính nó được, mà phải nhờ một component cha thiết lập thuộc tính cho nó, và giá trị đó sẽ cố định trong suốt vòng đời của component đó. Đối với các thuộc tính thường xuyên thay đổi hoặc muốn thay đổi trong nội tại component ta cần sử dụng một khái niệm khác, gọi là state.
e. State
Với State, ta có thể maintain trạng thái và các thuộc tính của nó ngay trong nội tại component. State cũng có thể truy cập trong nội tại của component, tuy nhiên không như props, các component cha có thể không truy cập được vào state của component con.
Về tổng quát, bạn nên khởi tạo state ngay trong constructor của component, sau đó sử dụng hàm this.setState(object newState) để gán trạng thái cho component bất cứ khi nào bạn muốn. Và lưu ý rằng không nên truy cập và thay đổi trực tiếp bất cứ thuộc tính nào của state bằng cách gọi this.state.foo = ‘bar’, mà phải thực hiện thông qua hàm this.setState(‘bar’).
Ví dụ ta muốn làm một máy phiên dịch từ ngữ thành pizza thì có thể sử dụng this.state để lưu và chỉnh sửa những từ đã gõ. Ở đây mỗi khi ta nhập gì đó vào <TextInput> thì hàm onChangeText() sẽ gọi hàm this.setState() để gán giá trị text mới vào this.state.text. Ngay sau đó khi component được render ra màn hình, ta sẽ lấy this.state.text đó ra split, mapping thành những ký hiệu 🍕 và vẽ ra màn hình trong hàm render().
g. Style
Với React Native, bạn không cần dùng thêm một ngôn ngữ nào (như CSS) để qui định style cho các component khi vẽ lên màn hình. Tất cả những thứ bạn cần là sử dụng Javascript để tạo ra các object chứa các giá trị cần cho style.
Tất cả các core component hỗ trợ bởi React Native đều chấp nhận một props tên là ‘style’.
Các style name và giá trị được kế thừa từ CSS ngoài trừ việc chuyển sang sử dụng CamelCase để biểu thị. (Ví dụ: backgroundColor thay vì background-color của CSS). Điều đó tạo thuận lợi cho việc rút ngắn khoảng cách giữa lập trình mobile apps và web apps.
Một props chứa các giá trị của style có thể là một POJO (Plain Old Javascript Object) chứa một mảng các style. Tuy nhiên vì các component có thể phức tạp hơn khi project phát triển, để clean code ta thường sử dụng StyleSheet.create() để define nhiều styles cùng lúcCác style name và giá trị được kế thừa từ CSS ngoài trừ việc chuyển sang sử dụng CamelCase để biểu thị. (Ví dụ: backgroundColor thay vì background-color của CSS). Điều đó tạo thuận lợi cho việc rút ngắn khoảng cách giữa lập trình mobile apps và web apps.
h. Networking
Nhiều mobile apps cần phải load tài nguyên từ remote URL. Bạn cần phải tạo các POST request đến các REST API, và tải dữ liệu về thông qua GET request. Hoặc đơn giản bạn chỉ cần fetch các dữ liệu tĩnh ở đâu đó trên Internet về (Vd: tải một hình ảnh tĩnh,..).
Networking trong React Native được tạo ra từ hai API chính: Fetch và XMLHttpRequest. Cả hai đều được thiết kế để tương thích với API của trình duyệt, vì vậy:
- Lập trình viên Web không cần phải học một cách mới để tạo các network requests.
- Các thư viện đều được xây dựng trên nền tảng của 2 API trên cho React Native.
- Fetch API:
Ví dụ: Tải một content từ trang web tĩnh: fetch('https://iceteaviet.blogspot.com/hcmus.json')
Fetch cũng có thể thêm các tham số optional để customize HTTP request của bạn. Bạn có thể định rõ ra các header khi gửi POST request.
Bạn có thể tham khảo rõ hơn các ví dụ về Fetch API và các custom libraries khác tại đây hoặc đây.
i. Tích hợp React Native vào một ứng dụng có sẵn.
React Native rất tốt nếu bạn bắt đầu tạo ứng dụng với nó ngay từ đầu. Tuy nhiên đối với các project lớn nó cũng cực kì tốt khi thêm một vài SingleView hoặc user flow vào một dự án native có sẵn chỉ với một vài bước.
- Hiểu rõ bạn cần intergrate component nào
- Tạo một Podfile với subspec cho tất cả React Native components mà bạn muốn sử dụng trong native app
- Tạo và chỉnh sửa các component đó bằng Javascript.
- Thêm một event handler mới để tạo RCTRootView trỏ tới React Native component của bạn với tên AppRegistry mà bạn đã khai báo trong index.ios.js
- Chạy React Native server bằng cách gõ lệnh npm start, và Run ứng dụng native của bạn từ XCode
- Debug
- Deploy ứng dụng của bạn qua script ‘react-native-xcode.sh’
- Thưởng thức thành quả
Ngoài ra bạn cũng có thể làm ngược lại - intergrate một component tạo ra bằng native code (Swift, Java) vào ứng dụng React Native bằng cách sử dụng:
Import YourAwesomeComponent from ‘./com/icetea/native/component/yourawesomecomponent.js’
Bạn có thể tham khảo thêm tại đây hoặc bài blog sau.
Chúc các bạn học tốt và đừng quên để lại bình luận bên dưới nhé.