[RN][Redux] Redux Promise Middleware

Giới thiệu

Trong phần này chúng ta sẽ tiếp tục với một loại redux khác.

Redux Promise Middleware là thư viện gọn nhẹ cho việc thực thi resolve và reject kết quả từ promise với những điều kiện có thể update được.

"Redux Promise Middleware giúp tăng tốc tiến trình xử lý bất đồng bộ trong Redux. Nó cho phép chủ động hơn trong việc cập nhật cũng như gửi đi các hành động pending, hoàn thành và từ chối. Nó có thể kết hợp với redux-thunk để móc nối các hành động bất đồng bộ." - Theo tài liệu của  Redux Promise Middleware.

Redux Promise Middleware có sự khác nhau khi tiếp nhận các hành động từ phía của bạn và thêm vào các thuộc tính PENDING, FULFILLED, hoặc REJECTED phụ thuộc vào điều kiện trả về của Promise.

Ví dụ, nếu như bạn gọi hành động FETCHING như thế này:

function fetchData() {
 return {
   type: FETCH_DATA,
   payload: getPeople()
 }
}

Thì hành động chờ lấy dữ liệu FETCH_DATA_PENDING sẽ được gửi đi một cách tự động.

Ngay khi phương thức getPeople được giải quyết xong, có sẽ gọi tới các phương thức kết quả như FETCH_DATA_FULFILLED hoặc FETCH_DATA_REJECTED phụ thuộc vào điều kiện trả về của phương thức getPeople.

Nhằm hiểu rõ hơn về điều này chúng ta sẽ áp dụng nó vào project của chúng ta.

Bắt đầu hãy update các giá trị constant để phù hợp với phương thức làm việc của chùng ta. Trong file constants.js:

export const FETCH_DATA = 'FETCH_DATA'
export const FETCH_DATA_PENDING = 'FETCH_DATA_PENDING'
export const FETCH_DATA_FULFILLED = 'FETCH_DATA_FULFILLED'
export const FETCH_DATA_REJECTED = 'FETCH_DATA_REJECTED'

Kế tiếp, trong file actions.js chúng ta update action của chúng ta thành 1 action đơn lẻ FETCH_DATA:

import { FETCH_DATA } from './constants'
import getPeople from './api'

export function fetchData() {
  return {
    type: FETCH_DATA,
    payload: getPeople()
  }
}

Và giờ, trong reducer (dataReducer.js) chúng cần đảo lại vị trí các actions với các giá trị constants mới để làm việc được:

import { FETCH_DATA_PENDING, FETCH_DATA_FULFILLED, FETCH_DATA_REJECTED } from '../constants'
const initialState = {
  data: [],
  dataFetched: false,
  isFetching: false,
  error: false
}

export default function dataReducer (state = initialState, action) {
  switch (action.type) {
    case FETCH_DATA_PENDING:
      return {
        ...state,
        data: [],
        isFetching: true
      }
    case FETCH_DATA_FULFILLED:
      return {
        ...state,
        isFetching: false,
        data: action.payload
      }
    case FETCH_DATA_REJECTED:
      return {
        ...state,
        isFetching: false,
        error: true
      }
    default:
      return state
  }
}

Cuối cùng, chúng ta chỉ cần update lại configureStore để sử dụng Redux Promise Middleware:

import { createStore, applyMiddleware } from 'redux'
import app from './reducers'
import promiseMiddleware from 'redux-promise-middleware';

export default function configureStore() {
  let store = createStore(app, applyMiddleware(promiseMiddleware()))
  return store
}

Và chúng ta sẽ chạy thử ứng dụng và sẽ nhận được kết quả tương đương với cách trước đó.

Kết Luận

Hơn tất cả, tôi nghĩ Saga nên dùng cho những ứng dụng phức tạp, và Redux Promise Middleware dùng cho những thứ còn lại ít phức tạp hơn. Tôi thực sự thích cách làm việc với những generators và async-await của saga, code nó thực sự hứng thú và việc code trở nên vui vẻ hơn. Nhưng tôi lại thích sự nhẹ nhàng và đơn giản đến từ Redux Promise Middleware.

Nếu như tôi biết sử dụng RXJS khá hơn một chú, tôi có thể app dụng Redux Observable nhưng vẫn có một số thứ mà tôi thực sự chưa hiểu sâu nên tôi sẽ ko sử dụng nó trong các ứng dụng production của mình.

Và đây là toàn bộ repo của bài viết https://github.com/react-native-training/redux-4-ways

Hẹn gặp lại trong bài viết tiếp theo. Cảm ơn bạn đã đọc bài viết này.