/
Redux - Middleware (3h)

Redux - Middleware (3h)

Middleware khá phổ biến với các Framework server-side, nó được đặt giữa thời điểm server nhận request và thời điểm server response. Ở Redux, Middleware giải quyết vấn đề khác với các Framework server-side nhưng định nghĩa có phần tương tự:

It provides a third-party extension point between dispatching an action, and the moment it reaches the reducer.

Hiểu một cách đơn giản middleware cho phép chúng ta can thiệp vào giữa thời điểm dispatch một action và thời điểm action đến được reducer. Chúng ta có thể thấy sự thay đổi của flow khi có sử dụng middleware qua hình dưới:

 

Sử dụng Middleware

Để sử dụng được Middleware chúng ta cần sử dụng function applyMiddleware của redux khi khởi tạo store

index.js

import { createStore, applyMiddleware } from 'redux'; import 'yourMiddleware' from 'your-middleware'; import rootReducer from './reducers/rootReducer'; const store = createStore(rootReducer, applyMiddleware(yourMiddleware));

 

Hiện nay redux đang có khá nhiều nhiều thư viện middleware bao gồm:

Redux-saga , redux-promise, redux-effects, redux-thunk, redux-connect, redux-loop, redux-side-effects, redux-logic, redux-observable, redux-ship

Nhưng nói chung trong đám kể trên thì chỉ có 3 cái tên xuất chúng nhất, được dùng phổ biến là:

  • Redux-Saga

  • Redux-Thunk

  • Redux-Observable

Ở đây chúng ta sẽ tìm hiểu về Redux-Observable

Redux-Observable

Giới thiệu

Redux Observable sử dụng RxJs và các đối tượng observable để tạo ra các tiến trình bất đồng bộ và luồng xử lý dữ liệu cho ứng dụng Redux.

Ứng dụng

https://drive.google.com/file/d/1S2AMpHwU5TqGkClytuIMm1KSfxnDb7PU/view?usp=sharing

Xem ví dụ sau, phát triển dựa theo bài trước:

Ở đây ta sẽ tạo một action getTemperature, có nhiệm vụ lấy nhiệt độ hiện tại. Để tiết kiệm thời gian viết api , ta sẽ fetch data từ một file .txt để đỡ tốn công viết api.

Tạo getResultEpic.js:

import {Observable} from 'rxjs'; import {GET_RESULT} from "../constants/ActionTypes"; import {getResultSuccess} from "../actions/GetResultActions"; import {combineEpics} from 'redux-observable'; /** * Get result epic * @param action$ * @returns {Observable<any>} */ function GetResultEpic(action$) { return action$.ofType(GET_RESULT) .mergeMap(action => Observable.from( new Promise((resolve, reject) => { /* fake to save time create api */ fetch( 'fakeresultapi.txt', { method: "GET", headers: { 'Accept': 'application/json', 'Content-Type': 'application/json', }, mode: 'cors' } ).then(response => response.json() .then(function (data) { if (response.ok) { return resolve(data); } else { return reject(data); } }) ).catch(() => reject('')) }) ).mergeMap( (response) => { return [ getResultSuccess(response) ] } ).catch( () => { return Observable.empty(); } ) ); } /** * */ export const getResultEpic = combineEpics( GetResultEpic, ); export default getResultEpic;

Combine epic:

import {combineEpics} from 'redux-observable'; import { BehaviorSubject } from 'rxjs/BehaviorSubject' import getResultEpic from "./GetResultEpic"; export default () => { const epic$ = new BehaviorSubject(combineEpics( getResultEpic )); const rootEpic = (action$, store) => epic$.mergeMap(epic => epic(action$, store) ); return rootEpic }

Đưa vào store:

Epic này sẽ chặn giữa khi action dispatch getResult và reducers, trước khi truyền vào reducer, ta sẽ fetch giá trị nhiệt độ. Sau khi có kết quả trả về, ta dispatch một action là getResultSuccess.

Get result success sẽ cập nhật lại state.

 

Related content

Redux - First Project (3h)
Redux - First Project (3h)
More like this
Exercise (6h)
More like this
Magento 2 Document
Magento 2 Document
Read with this
Redux - Introduction (3h)
Redux - Introduction (3h)
More like this
Simple POS (Client)
Simple POS (Client)
Read with this
ReactJs - Environment Setup (4h)
ReactJs - Environment Setup (4h)
More like this