React Native - Bạn biết những gì rồi

  1. Công nghệ thông tin

Được giới thiệu lần đầu vào tháng 01 năm 2015 tại React.js Conf. 2 tháng sau, Facebook chính thức open source React Native, khởi đầu cho quá trình biến nó trở thành một trong những JS Framework phổ biến nhất hiện nay.

React Native là gì?

React Native được phát triển bởi Facebook với mục đính ban đầu là áp dụng vào mạng xã hội lớn nhất hành tinh: Facebook. Do đặc tính công nghệ của mạng xã hội, Facebook cần phải tạo ra nền tảng phát triển ứng dụng di động đa nền tảng có hiệu năng không thua kém so với ứng dụng được phát triển độc lập cho từng nền tảng. React Native hiện tại chỉ hỗ trợ phát triển ứng dụng di động hệ điều hành Android và iOS, ít hơn so với Ionic (Android, iOS, Windows Phone).

React Native có gì hay?

React Native tạo ra ứng dụng native chứ không phải hybrid app như ionic,... Với 100% Native UI, React Native tạo nên sự “mượt mà” trong việc render UI và xóa nhòa khoảng cách về hiệu năng giữa ứng dụng đa nền tảng so với ứng dụng độc lập nền tảng.

Hai hệ sinh thái

  • Một lý do lập trình mobile app rất khó và tốn thời gian là vì thực tế bạn cần tìm hiểu 2 hệ sinh thái hoàn toàn khác biệt. Nếu bạn muốn lập trình app iOS, bạn phải học Swift hoặc Objective-C và Cocoa Pods. Nếu muốn lập trình app Android, bạn cần học Java và Android SDK. Tôi từng viết code với 3 ngôn ngữ là Swift, Objective C, Java và không thực sự hứng thú với việc tranh luận ngôn ngữ nào tốt hơn. Tuy nhiên, điều tôi có thể nói là chúng khác nhau và việc học từng ngôn ngữ đó sẽ tốn khá nhiều thời gian. Điều tương tự cũng xảy ra với các frameworks: Cocoa Touch và Android SDK. Tất nhiên, mỗi frameworks luôn có 1 gói các công cụ như công cụ testing, các libs, packages… và việc các dev phải cập nhật các tính năng mới nhất của mỗi hệ sinh thái là điều không thể bàn cãi.
  • Mặc khác, nếu bạn chọn lập trình trên React Native, phần lớn thời gian bạn sẽ chỉ cần học 1 bộ công cụ. Có rất nhiều thứ để bạn làm quen như: JavaScript, Node, React Native… nhưng chỉ có 1 công cụ duy nhất để học.

Khả năng sử dụng lại

  • Khả năng sử dụng lại đóng vai trò quan trọng trong lập trình phần mềm, nên mỗi khi bạn có thể sử dụng lại code thì React Native là công cụ tốt.
  • React Native không phải chỉ viết 1 lần mà nó chạy platform ở mọi nơi. Bất cứ khi nào bạn lập trình 1 app, bạn cần phải xây dựng UI trông native. Vì lý do này, 1 số UI code cần được viết theo đúng các chỉ dẫn và chuẩn mực tốt nhất của platform đó. Tuy nhiên, sẽ luôn có vài UI code thông dụng có thể được chia sẻ chung với nhau cùng tất cả logic. Tính năng “có thể chia sẻ code” có rất nhiều lợi điểm như: tận dụng nguồn nhân lực tốt hơn, duy trì ít code hơn, ít bugs hơn, các tính năng trong cả 2 platforms cũng tương tự nhau
  • Học 1 lần, viết ở mọi nơi: Khi team của Facebook tạo React Native, mục tiêu của họ là giúp các dev học 1 lần nhưng sử dụng được mọi platform. Bởi vì tất cả code của Android và iOS sử dụng cùng bộ công cụ, nên ý tưởng có 1 team dev làm app cho cả 2 platform là thực hiện được – 1 điều ít khi xảy ra khi có rất ít dev lập trình cả 2 platform iOS và Android. Thậm chí, tôi còn cho rằng team đang lập trình web app sử dụng React.js sẽ không phải cực khổ nữa khi học lập trình React Native và bắt đầu làm mobile app.

Declarative API: Khi bạn tạo ứng dụng sử dụng React Native, việc dự đoán và hiểu UI của bạn cũng dễ dàng hơn vì nó có 1 declarative API, tương phản với imperative API. Sự khác biệt giữa các cách tiếp cận này là khi bạn có 1 app với nhiều trạng thái khác nhau, bạn cần phải theo dõi các thay đổi trong UI và chỉnh sửa chúng. Điều này có thể là 1 nhiệm vụ phức tạp và không thể dự đoán được khi app của bạn phát triển. Đây được gọi là Imperative Programming. Nếu bạn dùng React Native vốn đã có declarative APIs, bạn chỉ cần quan tâm đến tình trạng UI hiện tại trông như thế này, mà không cần theo dõi những UI cũ.

Hot Reloading: Thói quen thông thường của dev khi code là test các thay đổi mỗi lần code được viết. Để thực hiện được, app cần phải được tổng hợp lại và và cài đặt hoặc trong 1 simulator hoặc 1 thiết bị thật sự. Với React Native, phần lớn thời gian, bạn không cần phải tổng hợp lại app mỗi lần có thay đổi. Bạn chỉ cần làm mới app trong simulator, emulator hoặc thiết bi. Thậm chí còn có 1 tính năng là Live Reload để tự động refresh app mỗi lần phát hiện 1 thay đổi trong code.


Nguồn mở

  • React Native vẫn còn là 1 công nghệ rất mới, mới chỉ trở thành nguồn mở chưa tới 1 năm về trước. Tuy vẫn còn vài bugs, nhưng nhìn chung, các dev có thể sử dụng React Native vào giai đoạn sản xuất ở hầu hết các mobile app. Ngoài ra vẫn còn vài tính năng có sẵn trong các frameworks native, chưa sử dụng được với React Native nhưng đây không phải là vấn đề lớn. Từ kinh nghiệm của bản thân, đây chỉ là chuyện đơn giản khi bạn đã quen thuộc với lập trình native. Thêm nữa, từ khi React Native đã là nguồn mở, 1 cộng đồng lớn các dev đã hỗ trợ thực hiện nhiều tính năng hơn, fix bugs… Phần lớn thời gian, nếu bạn đang cố gắng lập trình 1 thứ gì đó đã quen thuộc trong mobile apps thì nhiều khả năng là nó đã được lập trình rồi.
  • Như bạn thấy, tôi thực sự rất lạc quan về React Native. Tôi vẫn nhớ lập trình Android và iOS native nhưng đồng thời rất hứng thú khi sử dụng React Native thời gian qua. Tôi nghĩ React Native sẽ là game-changer – kẻ thay đổi cục chơi trong lập trình mobile và khó lòng đợi được cho đến lúc nó trở thành platform không thể bỏ qua để lập trình mobile!

Bắt đầu với React Native

Tuy có hàng loạt các lợi ích như vậy, nhưng không thể không kể đến các bất lợi mà React Native mang đến, một trong số đó, là vấn đề về các công nghệ đi kèm. Khi người ta nhắc đến react, họ cũng sẽ đề cập đến Redux, Redux-saga, React navigation, React Persisit, Immutable, Sass, ... quá nhiều công nghệ kèm theo, khiến các lập trình viên trở nên quá tải, và khá khó khăn để start.

Mình tạo topic này, với mong muốn rằng bản thân và tất cả mọi người có thể đóng góp, chia sẻ các kiến thức về React Native, các công nghệ xoay quanh nó nhằm nâng cao hơn trình độ bản thân, giúp đỡ những người mới bắt đầu. Thanks.

Từ khóa: 

react

,

vtcc_intern_7

,

công nghệ thông tin

TỔNG QUAN VỀ REDUX

1.Giới thiệu

Redux là một thư viện giúp bạn quản lí trạng thái của ứng dụng. Nó được thiết kế dựa trên Flux, nhưng giảm bớt những đau khổ thường gặp phải khi viết một ứng dụng Flux.

2. Kiến trúc trong Redux


VIEW PROVIDER: Đại diện cho một View Framework để đăng ký với STORE. Trong đó View Framework có thể là React hoặcAngular,...

ACTION: Là một đối tượng thuần thúy được tạo ra để lưu trữ thông tin liên quan tới sự kiện của người dùng (Nhấn chuột trên giao diện,..), nó bao gồm các thông tin như: Kiểu hành động, xẩy ra lúc nào, ở đâu, tọa độ, mục đính để thay đổi state nào,.

STORE: Quản lý trạng thái của ứng dụng, và có hàm dispatch(action).

MIDDLEWARE: (Phần mềm trung gian) Cung cấp một cách để tương tác với các đối tượng Action được gửi đến STORE trước khi chúng được gửi tiếp đến REDUCER. Tại Middleware bạn có thể thực hiện các nhiệm vụ như ghi lại nhật ký, báo cáo lỗi, tạo các "yêu cầu không đồng bộ" (asynchronous requests), hoặc phân phát (dispatch) các action mới,...

REDUCER: (Bộ biến đổi) Là một hàm thuần thúy để trả về một trạng thái mới từ trạng thái ban đầu. Chú ý: REDUCUER không thay đổi trạng thái của ứng dụng, thay vào đó nó sẽ tạo ra một bản sao chép của trang thái ban đầu, và sửa đổi nó để có một trạng thái mới.

g là bộ đôi kết hợp hoàn hảo với React (React Js và React Native)

3. Nguyên tắc

1. Single source of truth

Toàn bộ state của ứng dụng được lưu trữ trong một cây object tại một store duy nhất. Lý thuyết này nhằm giúp giới hạn sự trùng lặp dữ liệu và liên kết dữ liệu giữa các đối tượng khác nhau.

2. State is read-only

Cách duy nhất để thay đổi state là đưa ra một action -- một object mô tả hoạt động

3. Sự thay đổi được tạo bởi pure function

Pure function là function chỉ return giá trị được tạo bởi chính tham số của function

4. Data follow in Redux


  • UI gọi tới store.dispatch(action)
  • Reducer store gọi reducer nhận state hiện tại và action vừa được gửi đi
  • Root reducer có thể kết hợp nhiều reducer trong state tree để đưa ra kết quả - state tiếp theo của ứng dụng. Sử dụng combineReducers().
  • Store lưu toàn bộ state được trả về bởi root reducer.

5. Kết luận

Vậy là chúng ta đã tìm hiểu được những khái niệm cơ bản đầu tiên của Redux như nguyên lý, cấu trúc, và data flow.

Thông qua bài viết này hi vọng mọi người hình dung được các thành phần và cách làm việc của Redux trong một application

Trả lời

TỔNG QUAN VỀ REDUX

1.Giới thiệu

Redux là một thư viện giúp bạn quản lí trạng thái của ứng dụng. Nó được thiết kế dựa trên Flux, nhưng giảm bớt những đau khổ thường gặp phải khi viết một ứng dụng Flux.

2. Kiến trúc trong Redux


VIEW PROVIDER: Đại diện cho một View Framework để đăng ký với STORE. Trong đó View Framework có thể là React hoặcAngular,...

ACTION: Là một đối tượng thuần thúy được tạo ra để lưu trữ thông tin liên quan tới sự kiện của người dùng (Nhấn chuột trên giao diện,..), nó bao gồm các thông tin như: Kiểu hành động, xẩy ra lúc nào, ở đâu, tọa độ, mục đính để thay đổi state nào,.

STORE: Quản lý trạng thái của ứng dụng, và có hàm dispatch(action).

MIDDLEWARE: (Phần mềm trung gian) Cung cấp một cách để tương tác với các đối tượng Action được gửi đến STORE trước khi chúng được gửi tiếp đến REDUCER. Tại Middleware bạn có thể thực hiện các nhiệm vụ như ghi lại nhật ký, báo cáo lỗi, tạo các "yêu cầu không đồng bộ" (asynchronous requests), hoặc phân phát (dispatch) các action mới,...

REDUCER: (Bộ biến đổi) Là một hàm thuần thúy để trả về một trạng thái mới từ trạng thái ban đầu. Chú ý: REDUCUER không thay đổi trạng thái của ứng dụng, thay vào đó nó sẽ tạo ra một bản sao chép của trang thái ban đầu, và sửa đổi nó để có một trạng thái mới.

g là bộ đôi kết hợp hoàn hảo với React (React Js và React Native)

3. Nguyên tắc

1. Single source of truth

Toàn bộ state của ứng dụng được lưu trữ trong một cây object tại một store duy nhất. Lý thuyết này nhằm giúp giới hạn sự trùng lặp dữ liệu và liên kết dữ liệu giữa các đối tượng khác nhau.

2. State is read-only

Cách duy nhất để thay đổi state là đưa ra một action -- một object mô tả hoạt động

3. Sự thay đổi được tạo bởi pure function

Pure function là function chỉ return giá trị được tạo bởi chính tham số của function

4. Data follow in Redux


  • UI gọi tới store.dispatch(action)
  • Reducer store gọi reducer nhận state hiện tại và action vừa được gửi đi
  • Root reducer có thể kết hợp nhiều reducer trong state tree để đưa ra kết quả - state tiếp theo của ứng dụng. Sử dụng combineReducers().
  • Store lưu toàn bộ state được trả về bởi root reducer.

5. Kết luận

Vậy là chúng ta đã tìm hiểu được những khái niệm cơ bản đầu tiên của Redux như nguyên lý, cấu trúc, và data flow.

Thông qua bài viết này hi vọng mọi người hình dung được các thành phần và cách làm việc của Redux trong một application

Lương bổ sung thêm thông tin đi em.

Redux Saga - thư viện middleware hiệu quả cho Redux

I. Giới thiệu

Chào bạn, nếu đang đọc bài viết này thì chắc hẳn bạn đã có chút kiến thức về 

React native
 và 
redux
. Trong các dự án thực tế sử dụng React native, một phần rất quan trọng và gần như chắc chắn phải có đó chính là middleware.

1. Middleware là gì mà quan trọng đến vậy?

Một ứng dụng thực tế thường đòi hỏi có những thao tác xử lý cần thời gian để phản hồi ( các thao tác bất đồng bộ lấy dữ liệu từ api hay các thao tác đọc ghi file hay đọc cookie từ trình duyệt, ...). Các thao tác như vậy trong lập trình hàm gọi là side effects. Nhưng redux lại có một số ràng buộc:

  • Thứ nhất: Các xử lý trong Reducers phải là các hàm đồng bộ và pure, trả về state mới
  • Thứ hai: Reducers sẽ ko được sử dụng các hàm async vì không được thay đổi global state.

Do đó để có thể giải quyết được các side effect này ta cần thực hiện nó ở middeware.

2. Middleware trong Redux

Trong Redux, middleware là một lớp nằm giữa Reducers và Dispatch Action, nó sẽ modify và được gọi trước khi action được dispatch. Hiện nay có khá nhiều thư viện middleware cho redux nhưng nổi tiếng và được sử dụng nhiều nhất đó là redux-saga, redux-thunk và redux-observable.

Cả 3 thư viện trên đều có thể giải quyết được hầu hết các trường hợp. Mặc dù redux thunk khá dễ hiểu và dễ code nhưng nó chưa thực sự mạnh trong một số tình huống, điều này được khắc phục với các thư viện mạnh mẽ hơn như redux saga và redux observale.

Ok giờ bạn đã hiểu sự cần thiết của redux middleware để giải quyết vấn đề rồi. Trong phạm vi bài viết này tôi sẽ giới thiệu về thư viện redux saga.

II Hoạt động của Redux saga

1. Generator function

Để hiểu được sự hoạt động của redux saga bạn cần hiểu một số khái niệm cơ bản như generator function. Generator function là function có khả năng hoãn lại quá trình thực thi mà vẫn giữ nguyên được context. Hơi khó hiểu phải không, nói một cách đơn giản thì generator function là 1 function có khả năng tạm ngưng trước khi hàm kết thúc (khác với pure function khi được gọi sẽ thực thi hết các câu lệnh trong hàm), và có thể tiếp tục chạy tại một thời điểm khác. Chính chức năng mới này giúp ta giải quyết được việc bất đồng bộ, hàm sẽ dừng và đợi async chạy xong rồi tiếp tục thực thi.

2. Hoạt động

Bây giờ ta sẽ đi chi tiết vào hoạt động của redux-saga để hiểu nó làm gì để giải quyết các side effect


Redux saga cung cấp các hàm helper effect, các hàm này sẽ trả về một effect object chứa đựng thông tin đặc biệt chỉ dẫn middeware của Redux có thể thực hiện tiếp các hành động khác. Các hàm helper effect sẽ được thực thi trong các generator function.

Một số helper trong redux saga:

  1. takeEvery() : thực thi và trả lại kết quả của mọi actions được gọi.
  2. takeLastest() : có nghĩa là nếu chúng ta thực hiện một loạt các actions, nó sẽ chỉ thực thi và trả lại kết quả của của actions cuối cùng.
  3. take() : tạm dừng cho đến khi nhận được action
  4. put() : dispatch một action.
  5. call(): gọi function. Nếu nó return về một promise, tạm dừng saga cho đến khi promise được giải quyết.
  6. race() : chạy nhiều effect đồng thời, sau đó hủy tất cả nếu một trong số đó kết thúc

III Ví dụ

Chúng ta sẽ thực hiện một ví dụ để hiểu cách thực hiện redux saga trong Project. Ở đây ta sẽ thực hiện một hành động đó là lấy danh sách các bộ phim từ server. Để thực thi một Saga, trước hết chúng ta cần tạo một action. Trong file actions.js, ta thêm đoạn code sau:

import { FETCHING_FILM_LIST} from'./constants' 
export function fetchData() {
    return { type: FETCHING_FILM_LIST } 
} 
    

Chúng ta tạo một function để lấy dữ liệu film từ api và đặt nó trong file api.js

export function getFilm() {
      return fetch('https://facebook.github.io/react-native/movies.json')
               .then((response) => response.json())
               .then((result) => { return result.movies })
               .catch((error) => { console.log(error) })
} 

Chúng ta tạo file reducer có tên là app và đặt vào file reducer.js

import { FETCHING_FILM_LIST, FETCHING_FILMS_SUCCESS, FETCHING_FILMS_FAIL } from './constants' 
export default app = (state=[], action) => {
    switch(type) {
         case FETCHING_FILMS_SUCCESS:
                 return action.data
         case FETCHING_FILMS_FAIL:
                 return state
         default:
                 return state
    }
 }

Các bạn tạo một file mới saga.js và thêm vào đoạn code sau để có thể thêm một action bất đồng bộ khi action fetchData thực thi:

import { FETCHING_FILM_LIST, FETCHING_FILMS_SUCCESS, FETCHING_FILMS_FAIL } from './constants' 
import { put, takeEvery } from 'redux-saga/effects' 
import getFilms from './api' 
function* fetchFilms (action) { 
    try { 
        const data = yield getFilm() 
        yield put({ type: FETCHING_FILMS_SUCCESS, data }) 
    } catch (e) { 
        yield put({ type: FETCHING_FILMS_FAIL }) 
    }
} 

function* filmSaga () { 
        yield takeEvery(FETCHING_FILM_LIST, fetchFilms) 
} 

export default filmSaga 

Chúng ta import phương thức put và takeEvery từ redux-saga/effects. Khi chúng ta gọi phương thức put, redux saga sẽ hướng middleware tới thực thi một action. takeEvery là phương thức lắng nghe kết quả trả về của hành động FETCHING_FILM_LIST và gọi về một phương thức cakback là fetchFilms

Khi phương thức fetchFilms đc gọi, sau khi thực hiện getFilm() trả về thành công thì nó sẽ thực thi hành động FETCHING_FILMS_SUCCCESS.

Chúng ta tạo file configureStore.js để sử dụng saga middleware.

import { createStore, applyMiddleware } from 'redux' 
import app from './reducers' 
import createSagaMiddleware from 'redux-saga' 
import dataSaga from './saga' 

const sagaMiddleware = createSagaMiddleware() 
export default function configureStore() { 
       const store = createStore(app, applyMiddleware(sagaMiddleware))       sagaMiddleware.run(dataSaga) 
      return store 
} 

Những điểm chính cần lưu ý trong file này là nếu chúng ta import saga và cũng createSagaMiddleware từ thư viện redux-saga. Khi chúng ta tạo ra store, chúng ta sẽ pass mọi thứ cho sagaMiddleware mà chúng ta đã tạo ra và gọi sagaMiddleWare.run trước khi mọi thứ được lưu trữ ở store.

Chạy ứng dụng và bạn sẽ nhận được danh sách các bộ phim để có thể đẩy dữ liệu ra view.

IV Kết luận

Thông qua các lý thuyết và ví dụ cụ thể, mong các bạn đã có cái nhìn tổng quát về redux saga cũng như cơ chế hoạt động của nó. Chúc các bạn có thể áp dụng được redux saga trong các dự án thực tế của mình