React Native - Tương lai của lập trình di động

React được Facebook giới thiệu tới cộng đồng lập trình viên vào khoảng 2 năm trước, từ thời điểm đó cho đến nay, React đã phát triển một cách nhanh chóng không chỉ trong nội bộ facebook mà còn cả cộng đồng bên ngoài. Hiện nay, rất nhiều dự án đã được xây dựng dựa trên React, tỷ lệ các lập trình viên chọn và sử dụng React ngày càng nhiều vì nó giúp tiết kiệm thời gian “chiến đấu” với framework và tập trung hơn vào sản phẩm của mình hơn.

Với công nghệ web, việc kết hợp React với Redux giúp chúng ta có thể xây dựng rất nhiều ứng dụng tuyệt vời. Tuy nhiên, web chỉ là một phần mà React làm được. Với những hạn chế của các ứng dụng web, các ứng dụng Android và IOS đang dần lên ngôi. Tuy nhiên không phải ai đang lập trình web cũng có thể chuyển sang lập trình IOS và Android một cách dễ dàng và đó chính là lý do React-Native ra đời.

  • React Native sử dụng ngôn ngữ Java Script cực kì thân thiện: Một lập trình viên có thể lập trình tốt cho cả hai nền tảng Android và iOS chỉ với một ngôn ngữ duy nhất là javascript.
    React Native tạo ra những Native App (không phải Web App), tạo nên sự trải nghiệm tuyệt vời cho người dùng: tốc độ nhanh, tương tác phần cứng thiết bị một cách hoàn hảo.

React Native ra đời vì lý do đó, nó giúp cho các lập trình viên vốn đã quen thuộc với ngôn ngữ web, đặc biệt là javascript có thể viết được các ứng dụng trên Android và IOS với trải nghiệm Native thực thụ. Việc này cách đây mấy năm dường như là không thể đối với PhoneGap hay các công nghệ tương tự. Nhưng đúng như tiêu chí của React Native – “Học một lần, sử dụng nhiều nơi”.

Vậy chúng ta cùng bắt tay vào tìm hiểu những điều cơ bản nhất của React Native để nhanh chóng xây dựng cho mình một ứng dụng mobile thực sự. Một ứng dụng đêm lại trải nghiệm native.

Cách React Native hoạt động

Ứng dụng được viết bằng React Native được chia làm 2 phần:

  • Phần view: Nếu đã từng làm việc với React, bạn không còn lạ lẫm gì với khái niệm Virtual DOM của React, mọi xử lý được thực hiện trên 1 cây DOM ảo, với React Native các Component như Tab, Touch… đã được facebook xây dựng sẵn, khi build ứng dụng sẽ được render lại bằng native view.
  • Phần xử lý : Các phần xử lý logic, tương tác người dùng được thực thi dưới bộ core của javascript, không phải thông dịch qua Java hay Objective-C.

Style trong React Native

Với React Native, chúng ta không sử dụng một ngôn ngữ đặc biệt hay một cú pháp nào đó để định nghĩa style ở phần view. Với các ứng dụng Android, khi bạn tạo 1 view nào đó bạn phải sử dụng các thẻ xml được quy định bởi google, các thẻ XML như LinearLayout, TableLayout để chia các thành phần trong component của mình, nhưng với React Native bạn chỉ sử dụng javascript, tất cả các core component đều được sử dụng 1 Prop name là style.

Style này làm việc giống như thẻ style trong html đối với lập trình web. Đối với các component phức tạp, chúng ta có thể định nghĩa phần style riêng để code trở nên clear hơn bằng cách sử dụng StyleSheet.create để định nghĩa bên ngoài.

Layout với FlexBox

FlexBox được facebook thiết kế để cung cấp layout trên những size màn hình khác nhau. Khi làm việc với layout trong React-Native chúng ta thường làm việc với các thuộc tính sau : flexDirection, alignItems, justifyContent, để hoàn thành layout. FlexBox làm việc giống CSS trên web nhưng có một vài điểm khác biệt.

  • flexDirection:  mặc định sẽ là cột thay vì hàng, flexDirection được khai báo trong thẻ style của layout đó. Nó sẽ tổ chức giao diện theo chiều ngang hoặc chiều dọc tùy thuộc vào tham số chúng ta truyền vào.
  • Justify Content: Nếu khai báo thuộc tính này, các thành phần con của bạn sẽ được phân bố vị trí bởi các thuộc tính bạn truyền vào cho nó. Các thuộc tính được hỗ trợ bởi facebook là : flex-start, center, flex-end, space-around, space-between. Tùy thuộc vào yêu cầu bài toán về giao diện bạn sẽ tự thiết kế giao diện của mình dựa vào các thuộc tính trên. Nếu đã biết qua về Android,  có vẻ như giao diện của bạn sẽ được thiết kế nhanh và đơn giản hơn so với việc sử dụng các Layout như xml trong Android.
  • alignItems: mặc định sẽ là kiểu *stretch *thay vì flex-start
import React, { Component } from 'react';
import { AppRegistry, View } from 'react-native';

class FlexDirectionBasics extends Component {
  render() {
    return (
      // Try setting `flexDirection` to `column`.
      <View style={{flex: 1, flexDirection: 'row'}}>
        <View style={{width: 50, height: 50, backgroundColor: 'powderblue'}} />
        <View style={{width: 50, height: 50, backgroundColor: 'skyblue'}} />
        <View style={{width: 50, height: 50, backgroundColor: 'steelblue'}} />
      </View>
    );
  }
};

AppRegistry.registerComponent('AwesomeProject', () => FlexDirectionBasics);

Đoạn code trên chúng ta đang khai báo 1 vierw lớn, có kiểu hàng ngang, bao gồm 3 view nhỏ với chiều cao và độ dài tương ứng của mỗi view con là 50. Bạn có thể nhận thấy ưu điểm rất rõ ràng của FlexBox trong việc chia layout cho app trên màn hình dễ dàng như thế nào? Và trên đây là là các thuộc tính cơ bản để chúng ta có thể dựng được khung của giao diện như ý muốn trên các size màn hình khác nhau.

Ngoài ra, React-Native còn hỗ trợ rất nhiều các thuộc tính khác như padding, margin, Zindex giống như trong CSS. Chúng ta có thể đọc và tìm hiểu thêm tại link sau: https://facebook.github.io/react-native/docs/layout-props.html

Xử lý với TextInput

TextInput là 1 component cơ bản cho phép người dùng nhập text, nếu làm việc với ReactJs khi bắt sự kiện với thẻ Input trong html chúng ta sử dụng hàm onChange thì với ReactNative chúng ta sử dụng hàm onChangeText, hàm này sẽ được gọi bất cứ khi nào chúng ta có một thao tác nhập hoặc xóa text trong thẻ input, hàm onChangeText được sử dụng cùng với hàm onSubmitEditing khi chúng ta submit data.

import React, { Component } from 'react';
import { AppRegistry, Text, TextInput, View } from 'react-native';

class PizzaTranslator extends Component {
  constructor(props) {
    super(props);
    this.state = {text: ''};
  }

  render() {
    return (
      <View style={{padding: 10}}>
        <TextInput
          style={{height: 40}}
          placeholder="Type here to translate!"
          onChangeText={(text) => this.setState({text})}
        />
        <Text style={{padding: 10, fontSize: 42}}>
          {this.state.text.split(' ').map((word) => word && '?').join(' ')}
        </Text>
      </View>
    );
  }
}

AppRegistry.registerComponent('PizzaTranslator', () => PizzaTranslator);

ListView trong React-Native

ListView như chúng ta được biết là 1 component hiển thị theo chiều dọc khi lượng data chúng ta lấy được vượt quá sự hiển thị của màn hình, giúp cho màn hỉnh hiển thị được nhiều thông tin hơn, đầy đủ hơn.

ListView làm việc tốt nhất với các danh sách item dài, khi mà số lượng item có thể thay đổi theo thời gian. Chú ý rằng, ListView chỉ render các element hiển thị trên màn hình chứ không phải render hết 1 lượt ra.

ListView yêu cầu 2 tham số props là : dataSourcerenderRow

  • dataSource:  chính là source data danh sách của chúng ta
  • renderRow: sẽ lấy 1 item trong số đó và trả về format component để render
import React, { Component } from 'react';
import { AppRegistry, ListView, Text, View } from 'react-native';

class ListViewBasics extends Component {
  // Initialize the hardcoded data
  constructor(props) {
    super(props);
    const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
    this.state = {
      dataSource: ds.cloneWithRows([
        'John', 'Joel', 'James', 'Jimmy', 'Jackson', 'Jillian', 'Julie', 'Devin'
      ])
    };
  }
  render() {
    return (
      <View style={{paddingTop: 22}}>
        <ListView
          dataSource={this.state.dataSource}
          renderRow={(rowData) => <Text>{rowData}</Text>}
        />
      </View>
    );
  }
}

// App registration and rendering
AppRegistry.registerComponent('ListViewBasics', () => ListViewBasics);