posted by Nguyễn Thành Tuấn on 2016-05-11 00:33

REACT NATIVE LÀ GÌ?

 

React Native là 1 framework Javascript được dùng để viết các ứng dụng native cho iOS và Android. Đây là thư viện dựa trên React, là 1 thư viện Javascript do Facebook hình thành để xây dựng các giao diện người dùng trên các trình duyệt web. Và React Native được dùng trong việc phát triển các ứng dụng có nền tảng điện thoại. Hay nói cách khác: các nhà phát triển website bây giờ có thể viết các ứng dụng mobile được dùng bằng ngôn ngữ Javascript, ngôn ngữ rất được ưa thích của web developer. Một điểm cộng nữa đó là hầu hết code được viết có thể được dùng cho nhiều nền tảng, cho cả iOS và Android. 

Ưu điểm

  1. Các ưu điểm trong phần giới thiệu trên.
  2. React Native được xây dựng trên React, mà React lại làm việc một cách độc lập với UI thread chính, vì thế các ứng dụng được viết có thể duy trì hiệu năng cao.
  3. Giả sử rằng bạn đang làm việc với React trên webweb thì bạn có thể viết các ứng dụng mobile bằng React Native với việc thực thi hiệu năng, debug,... bằng chính các công cụ dùng trên web.
  4. Vì React Native đơn thuần là Javascript vì vậy bạn không cần rebuild lại ứng dụng để thay đổi các hiệu ứng,... Thay vào đó bạn chỉ cần nhấn CommanCommand + R (trên Mac) để refresh lại ứng dụng. Việc này sẽ giúp tiết kiệm khối thời gian cho bạn đấy.
  5. Điều mà tôi biết cuối cùng cho hàng vạn các ưu điểm đó là bạn có thể sử dụng các text editor bạn thích cho Javascript. Bởi vì React Native không tập trung bạn làm việc với Xcode hoặc Android Studio quá nhiều. Cross-plaftorm mà.
  6. ...

Nhược điểm 

  1. Nhược điểm có vẻ lớn nhất của React Native đó là "sự trưởng thành". Tất cả các tài liệu chắc chắn rằng đang dần cải thiện và nâng cấp. Một số tính năng trên iOS và Android vẫn chưa được hỗ trợ. 
  2. ...
    Mặc dù vậy, bản thân tôi từng là 1 iOS developer nguyên thuỷ (sử dụng Objective-C) nhưng khi tìm hiểu về React Native tôi vô cùng thích thú và điều quan trọng là tôi tin tưởng vào Mark Zuckerberg, tin vào Facebook. Nếu vậy thì tiếp theo tối xin giới thiệu về cách làm việc với React Native như thế nào.

LÀM VIỆC VỚI REACT NATIVE 

Vì phần này chỉ tập trung vào lý thuyết, mà phần giới thiệu tôi nói cũng khá nhiều và tôi nghĩ đa số các developers đều thích chạy được ứng dụng hơn đọc lý thuyết vì thế phần này tôi sẽ nói chi tiết hơn trong blog tiếp theo.

Tiếp theo tôi xin hướng dẫn cách build ứng dụng đầu tiên cho bạn.

Để xây dựng bất kỳ ứng dụng dựa trên bất cứ ngôn ngữ lập trình nào, bạn đều cần phải setup môi trường phải không nào? Các bạn cứ làm theo hướng dẫn theo đường link dưới đây là có thể setup được môi trường và chạy được ứng dụng cơ bản đầu tiên rồi đấy.

http://facebook.github.io/react-native/docs/tutorial.html#content

Nếu bạn qua được các bước cài đặt này thì bạn có thể bắt đầu với react native rồi. Thế nhiệm vụ của chap hướng dẫn này là gì....?

Vì là 1 developer nên tôi nghĩ việc cài đặt môi trường cho 1 ngôn ngữ lập trình cũng không khó, hơn thê nữa tài liệu hướng dẫn và chạy "HelloWorld" project cũng khá chi tiết.

Trong phần này tôi sẽ hướng dẫn các bạn tạo 1 ứng dụng có tên là "Weather Project", sau ứng dụng này bạn có thể biết được cách sử dụng các khái niệm cơ bản trong react-native:

  • Stylesheets
  • Flexbox
  • Giao tiếp với network
  • User input
  • Hình ảnh

"Weather Project" về cơ bản sẽ có 1 text field nơi người dùng nhập zipcode, dụa vào đó nó sẽ lấy dữ liệu từ OpenWeatherMap API và hiển thị nhiệt độ hiện tại.

LET"S START

Khởi tạo mới ứng dụng

Step 1. Tạo ứng dụng bằng lệnh terminal

react-native init WeatherProject

Step 2. Việc tiếp theo chúng ta cần làm là bạn có thể thay thế các đoạn code mặc định trong 2 file index.ios.js và index.android.js thành:

'use strict';

var React = require('react-native');
var { AppRegistry } = React;
var WeatherProject = require('./WeatherProject');

AppRegistry.registerComponent('WeatherProject', () => WeatherProject);
  • Dòng 1: sử dụng strict: http://www.w3schools.com/js/js_strict.asp
  • Dòng 5: điều này đồng nghĩa với việc chúng ta sẽ tạo thêm 1 file gọi là WeatherProject.js.
    Q: Tại sao chúng ta không remove các components và styles trong 2 file được thay thế code trên?
    A: Uhmmm... Tại sao chúng ta không code trên 1 file mà lại code trên 2 file nhỉ?
Step 3.
Tạo 1 file có tên WeatherProject.js (tên này tuỳ thuộc vào việc bạn định nghĩa ở dòng 5 phía trên)
Về cơ bản, trong file này code khởi tạo sẽ là:
import React, {Component} from 'react';
import {
  StyleSheet,
  Text,
  View,
} from 'react-native';

var WeatherProject = React.createClass({
  render() {
    return (
      <View style={styles.container}>
         <Text>
            Hope it run.
         </Text>
      </View>
    );
  }
});

var baseFontSize = 16;

var styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: 'center',
    paddingTop: 30
  },
});

module.exports = WeatherProject;

User Input

Chúng ta muốn user có thể nhập input code? Vì thế chúng ta cần tạo 1 textfield cho người dùng.

Step 1. Thêm phần này vào trước hàm render

getInitialState: function(){
    return {
      zip: ''
    };
  },
  • getInitialState là 1 trong các hàm trong lifecycle https://facebook.github.io/react/docs/component-specs.html
  • getInitialState là hàm dùng để khởi tạo các giá trị cho các components. Giá trị được trả về được dùng cho khởi tạo giá trị của this.state
  • this.state: một component có 1 biến toàn cục chung được duy trì đó là this.state. Một khi các giá trị trong state này được thay đổi thì hàm render sẽ được gọi lại để cập nhập. https://facebook.github.io/react/

Step 2. Trong hàm render thêm 2 components, đó là <Text> để hiển thị this.state.zip<TextInput> để người dùng nhập giá trị.

<View style={styles.container}>
          <Text style={styles.welcome}>
              You inputed {this.state.zip}.
          </Text>
          <TextInput style={styles.input}
            onSubmitEditing={this._handleTextChange}/>
      </View>

Bạn nhớ import thêm TextInput vào để mà có thể sử dụng được đó nhé.

Trong styles ta thêm 2 tuỳ chỉnh sau cho Text và TextInput.

welcome: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
  input: {
    fontSize: 20,
    borderWidth: 2,
    height: 40
    }
  • Chúng ta bàn luận về TextInput tí: nó là gì chắc các bạn cũng biết, nó là component cơ bản cho phép người dùng nhập các text, nó có thể lắng nghe các sự kiện như là onChange, onFocus,.... Nhưng chúng ta chưa cần sử dụng chúng vào lúc này.
    http://facebook.github.io/react-native/docs/textinput.html#content
  • Và bây giờ chúng ta sử dụng onSubmitEditing, hàm này được gọi khi button submit của input text được ấn (ở đây sẽ là button ''return' trên bàn phím điện thoại), hàm này sẽ bị vô hiệu hoá khi ta set multiline = true.
  • Và trong ứng dụng này ta sử dụng chúng để gọi hàm _handleTextChange
    _handleTextChange(event){
          console.log(event.nativeEvent.text);
          this.setState({
            zip: event.nativeEvent.text
          });
      },
    
  • Và nếu muốn, các bạn có thể thêm các điều kiện validate ở đây để đảm bảo rằng người sử dụng chỉ nhập được trong vòng 5 số.
  • Và bây giờ bạn có thể nhập text input vào và nhấn return trên bàn phím, những gì bạn nhập sẽ được hiển thị trên Text 'You inputed'.

HIỂN THỊ DỮ LIỆU

Bây giờ chúng ta sẽ hiển thị dữ liệu thông tin thời tiết cho zip code này. Nhưng chúng ta sẽ bắt đầu với dữ liệu giả (hay còn gọi với khái niệm 'mock data') bằng cách thêm dữ liệu vào trong hàm getInitialgetInitialState .

getInitialState: function(){
    return {
      zip: '',
      forecast: {
        main: 'Sun',
        description: 'so hot',
        temp: 38.0
      }
    };
  }

Tiếp theo chúng ta sẽ render dữ liệu này để hiển thị lên màn hình. Chúng ta sẽ tạo ra 1 component riêng để hiển thị các dữ liệu này bằng cách tạo 1 file mới tên là Forecast.js

Trước khi bắt tay, mời các bạn tìm hiểu qua cách lấy dữ liệu thông qua this.props. Cách này dùng để làm gì? Bạn có thể hiểu bằng ví dụ như thế này. Ta đã có component cha là WeatherProject, bây giờ ta đang tạo ra component con là Forecast và this.props cho phép ta truy cập dữ liệu cha từ component con. Các bạn có thể tham khảo tại: https://facebook.github.io/react/docs/tutorial.html (using props).

Và đây là code trong file Forecast.js

import React from 'react';
import {
  StyleSheet,
  Text,
  View,
} from 'react-native';

var Forecast = React.createClass({
  render: function() {
    return (
      <View>
        <Text style={styles.bigText}>
          {this.props.main}
        </Text>
        <Text style={styles.mainText}>
          Current conditions: {this.props.description}
        </Text>
        <Text style={styles.bigText}>
          {this.props.temp}°C
        </Text>
      </View>
    );
  }
});

var styles = StyleSheet.create({
  bigText: {
    flex: 2,
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
    color: '#000000'
  },
  mainText: {
    flex: 1,
    fontSize: 16,
    textAlign: 'center',
    color: '#000000'
  }
})

module.exports = Forecast;

Tiếp theo ta cần import Forecast.js vào trong WeatherProject.js:

  • Khai báo biên Forecast để sử dụng, dòng này đươcf khai báo phía trên "var WeatherProject = React.createClass..."
    var Forecast = require('./Forecast');
    
  • Sử dụng Forecast trong hàm render()
    render() {
        return (
          <View style={styles.container}>
              <Text style={styles.welcome}>
                  You inputed {this.state.zip}.
              </Text>
              <Forecast
                main={this.state.forecast.main}
                description={this.state.forecast.description}
                temp={this.state.forecast.temp}
              />
              <TextInput style={styles.input}
                returnKeyType='go'
                onSubmitEditing={this._handleTextChange}/>
          </View>
        );
      }
  • Các bạn có để ý dòng 13 không? eturnKeyType='go'
    Cho phép bạn custome nút return trên bàn phím đấy nhé :D
    Và kết quả của bước này đây

 

Nhin đơn điệu quá nhỉ? Bây giờ chúng ta sẽ thêm hình ảnh vào cho ngầu 1 tí

THÊM BACKGROUND IMAGE

Vì iOS và Android là 2 nền tảng khác nhau vì thế việc sử dụng hình ảnh cũng khác nhau.

Link hình ảnh: https://mega.nz/#F!V0M13Krb!feBfTsetA_DUcIEP9zU4wQ

Chúng ta sẽ bắt đầu với iOS, Xcode trước:

  1. iOS image
    Trong thư mục project các bạn mở thư mục ios và WeatherProject.xcodeproj bằng Xcode
    Trong Xcode, chọn Image.xcasset/ , sau đó chọn New Image Set . Lúc này bạn có thể kéo thả hình ảnh vào.
    Các bạn lưu ý các định nghĩa hình ảnh trong iOS bao gồm @2x, @3x nhé.
  2. Android Image
    Chúng ta sẽ add hình ảnh vào trong các thư mục bitmap drawable trong WeatherProject/android/app/src/main/res
    Bạn cần tạo ra các thư mục sau để giải quyết vấn đề đa màn hình trên Android và add hình ảnh vào trong các thư mục đó
  3. Xong bước này các bạn nhớ chạy lại lệnh react-native run-ios hoặc react-native run-android để refresh.
  4. Sau khi đã xong quá trình chuẩn bị hình ảnh, tiếp theo sẽ coding 1 chút
     <Image source={require('image!flowers')}
                      resizeMode='cover'
                      style={styles.backdrop}>
     </Image>
    
  5. Và điều chỉnh style 
    backdrop: {
        flex: 1,
        flexDirection: 'column'
      },
    
  6. Thêm 1 số components con cho Image, nhớ import Image ở đầu file và refactor lại hàm render luôn.
    render: function() {
        var content = null;
        if(this.state.forecast !== null){
          content = <Forecast
                      main={this.state.forecast.main}
                      description={this.state.forecast.description}
                      temp={this.state.forecast.temp}/>;
        }
        return (
          <View style={styles.container}>
              <Image source={require('image!flowers')}
                      resizeMode='cover'
                      style={styles.backdrop} >
                    <View style={styles.overlay}>
                        <View style={styles.row}>
                            <Text style={styles.mainText}>
                                Current weather for
                            </Text>
                            <View style={styles.zipContainer}>
                             <TextInput
                               style={[styles.zipCode, styles.mainText]}
                               onSubmitEditing={this._handleTextChange}/>
                           </View>
                        </View>
                        {content}
                    </View>
                </Image>
          </View>
        );
  7.  Tới lúc này các bạn quay lại file Forecast.js để điều chỉnh mã màu lại, từ #000000 thành #FFFFFF 
    var styles = StyleSheet.create({
      bigText: {
        flex: 2,
        fontSize: 20,
        textAlign: 'center',
        margin: 10,
        color: '#FFFFFF'
      },
      mainText: {
        flex: 1,
        fontSize: 16,
        textAlign: 'center',
        color: '#FFFFFF'
      }
    })
    
  8. Dưới đây là prototype style cho ứng dụng
  9. Xong, cơ bản về giao diện và hiển thị với mock data xong rồi.

Cuối cùng, tôi sẽ hướng dẫn các bạn lấy dữ liệu từ Web API về để hiển thị thay cho mock data.

LẤY DỮ LIỆU TỪ WEB

Trong React-native chúng ta không thể sử dụng jQuey để gửi request bởi Ajax từ các thiết bị điện thoại được, thay vào đó sẽ là :

fetch('http://www.somesite.com')
     .then((response) => response.text())
     .then((responseText) => {
       console.log(responseText);
     });

Trong ứng dụng của chúng ta sẽ sử dụng OpenWeatherMap API, để sử dụng được chúng ta cần gọi hàm trong textinput nơi nhập mã zipcode để query API, cụ thể như sau:

_handleTextChange(event){
      var zip = event.nativeEvent.text;
      this.setState({zip: zip});
      fetch('http://api.openweathermap.org/data/2.5/weather?q='
      + zip + '&appid=0ab71a03aacdab82753cf3e8e060caa6')
        .then((response) => res\.json())
        .then((responseJSON) => {
          this.setState({
            forecast: {
            main: responseJSON.weather[0].main,
            description: responseJSON.weather[0].description,
            temp: responseJSON.main.temp
          }
          });
        })
        .catch((error) => {
          console.console.warn(error);
        })
      this.setState({
        zip: event.nativeEvent.text
      });
  },

Lưu ý rằng, để sử dụng được API này bạn cần đăng ký 1 tài khoản trên trang web https://home.openweathermap.org/api_keys, việc này giúp sinh ra 1 app id giúp bạn có thể truy cập được dữ liệu.

Cuối cùng sản phẩm của bạn cũng đươc ra lò rồi :D

Chúc các bạn thành công nhé.
Full source code: https://mega.nz/#F!h1dBALYD!6WOrIxNKVrPd0TH6zUsDnQ

 


Leave a Comment

Fields with * are required.