Nay ta đi tìm hiểu về Custom Middleware, nhưng Middleware nó là gì? tại sao phải dùng middleware?
Middleware là gì?
Middleware cho phép ta chặn các dispatch actions(hành động) được gửi đến Reducers. Khi không được gửi đến Reducers thì dững nhiên là Store sẽ không được cập nhật. Chính vì thế tại thời điểm dispatch action đó ta có thể chặn hoặc huỷ bỏ actions trong Middleware
Đồng thời Middleware giúp bạn ghi logs, error reporting, thực hiện các yêu cầu không đồng bộ(asynchronous) và hơn thế nữa.
Middleware là nằm giữa dispatch vs Reducers, nên chúng ta có thể kiểm soát được actions được gửi đi
Mình nói thêm là redux-thunk nó cũng là một middleware cho phép ta gửi các aysnchronous actions, còn redux-logger ghi lại các hành động và thay đổi trạng thái
Tạo Middleware như thế nào?
Ở đây mình sẽ nói về middleware trong Redux, trước tiên ta cần phải import hàm middleware sau từ thư viện Redux
import { applyMiddleware } from "redux";
Giả sử chúng ta đang tạo một loggerMiddleware. Sau đó, để xác định Middleware, chúng ta cần sử dụng cú pháp sau:
const loggerMiddleware = (store) => (next) => (action) => { // your code };
Đồng thời nếu bạn muốn viết theo kiểu cơ bản như sau:
const loggerMiddleware = function (store) { return function (next) { return function (action) { // your code }; }; };
Khi chúng ta đã tạo function Middleware cho riêng mình rồi, ta sẽ thêm nó vào hàm applyMiddleware như sau:
import { createStore, applyMiddleware } from 'redux' import thunkMiddleware from 'redux-thunk'; import loggerMiddleware from './middleware/middleware-logger'; const store = createStore( //call reducers của bạn reducers, //ta có thể call nhiều middleware trong hàm applyMiddleware(thunkMiddleware, loggerMiddleware));
Ở đây mình nói thêm là hàm createStore() có 3 tham số:(reducer, initial state, middleware), những code trên ta chỉ khai báo có 2 tham số. Nhưng hàm createStore nó hiểu được là tham số thứ 2 là middleware. Vì nó thấy có cú pháp của các hàm lồng nhau.
Okay ta hãy chỉnh sửa lại hàm middleware chúng ta vừa tạo xem
const loggerMiddleware = (store) => (next) => (action) => { //chúng ta có thể console action ra xem như thế nào console.log("action", action); //show ra các state trong store console.log(store.getState()); //hoặc bạn có thể console action.payload console.log("payload",action.payload) /* * giống như ta đã nói, middleware nó nằm giữa dispatch vs reducers, nên ta có thể tùy chỉnh giá trị payload trong actions được gửi tới */ action.payload="hoanguyenit.com" /* * Tiếp tục next(action), là cho nó đi tiếp để nó đến reducer, sau đó nó sẽ cập nhật lại cửa hàng Store của ta * Còn nếu bạn không sử dụng next(action) thì nó tạm dừng tại đây, nó không đi đển được Reducers */ next(action); }; export default loggerMiddleware ;
Khi ta dispatch action đến reducers để cập nhật Store, thì nó chạy qua middleware này trước tiên, sao đó nó console.log("action",action), rồi nó tiếp tục next(action)
Trong trường hợp bạn không gọi next(action) nó sẽ dựng tại thời điểm console.log và không cập nhật store.
Bạn có thể viết xử lý middleware chính bạn như thế nào thì viết , có thể lên mạng tìm tòi cách viết nào đó hay rồi về chỉnh sửa lại middleware của mình
Trong Middleware bạn có thể gọi nhiều middleware cũng được nhé
const middleware = applyMiddleware(loggerMiddleware, secondMiddleware, thirdMiddleware);
Nó xử lý theo thứ tự nhé ,nó chạy hết middleware hết thì thôi
Middleware trong Redux-Toolkit như thế nào?
Nó cũng giống vậy thôi chỉ khác cách mà bạn gọi nó trong hàm configureStore().
import { configureStore } from '@reduxjs/toolkit'; import customMiddleware from '../features/comment/commentMiddleware'; import commentReducer from '../features/comment/commentSlice'; import counterReducer from '../features/counter/counterSlice'; export const store = configureStore({ reducer: { counter: counterReducer, comment: commentReducer }, middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(customMiddleware), });
Ta có thể gọi nhiều middleware trong concat nhé, ta sẽ sử dụng mảng concat([middlewareOne, MiddlewareTwo])
File customMiddleware.js
const customMiddleware = store => next => action => { console.log("middleware ",store.getState()) console.log(action) let data = action.payload; //gọi tiếp dispatch trong middleware next(action); } export default customMiddleware;
Mình nói thêm là API configureStore của Redux-Toolkit nó tự động thêm Middleware thunk trong quá trình tạo Store, do đó, thường có sẵn mà không cần cấu hình bổ sung.
Okay vậy là ta đã hiểu sơ qua về Middleware rồi , giờ là lúc bạn lên suy nghĩ sử dụng middleware cho chính ứng dụng của bạn
Con dùng Middleware vào mục tiêu gì? thì chỉ có bạn mới hiểu dc, bạn cần làm gì trong ứng dụng của bạn.
Chẳng hạn bạn gọi async callApi bạn có thể sử dụng redux-thunk, Kiểm tra nội dung trong payload trước khi gửi đến Reducers, cập nhật Store
Bạn có tìm hiểu về redux-thunk trong middleware nó dùng để làm gì? cấu hình sau, sử dụng thế nào? tại thường ta thường hay dispatch actions call api