Site icon Khoa Phạm BK Blog

Giới thiệu về Redux-Toolkit

Redux là 1 state management phổ biến trong hệ sinh thái React, nếu các bạn code React thì khả năng cao đã từng làm việc với Redux, kinh qua nhiều project hoặc chí ít cũng đã từng biết đến nó rồi. Redux được phát triển từ những năm 2015 và được ưa chuộng phổ biến giúp việc quản lý state trong React. Sau đó như mọi người biết ở version 16.8, React có trình làng React Hooks vào khoảng tháng 2 năm 2019. Bản thân Hooks sinh ra thì không liên quan gì lắm đến Redux, Hook nhằm giải quyết vấn đề tái sử dụng logic code. Tuy nhiên Hooks cũng có những tác động nhất định lên Redux, kết hợp với những vấn đề đã tồn đọng từ lâu trong phiên bản Redux core; chính vì thế team phát triển Redux cũng đã tìm cách khắc phục, cải thiện và đã cho ra mắt Redux Toolkit vào tháng 10 năm 2019.

Trong phần giới thiệu về Redux Toolkit, team Redux cũng đã giải thích chi tiết mục tiêu cho ra đời RTK (Redux Toolkit), bạn có thể đọc ở link sau và mình cũng xin trích ra dưới đây xem như phần định nghĩa cho Redux Toolkit:

https://redux-toolkit.js.org/introduction/getting-started

Redux Toolkit package giúp chuẩn hóa cách viết Redux logic, nó được tạo ra để giúp giải quyết 1 số vấn đề than phiền về Redux như sau:

Hẳn các bạn nếu làm việc nhiều với Redux cũng sẽ gặp phải những vấn đề trên. Để tạo ra được 1 store hoàn chỉnh chúng ta phải trải qua khá nhiều bước với các đoạn code lặp lại mà redux thì chả có cảnh báo cũng như xây dựng quy chuẩn nào rõ ràng cho việc đó. Rồi ai dùng Redux thì cũng add thêm nhiều thư viện middleware, selectors khác như thunk, saga, … thì mới có thể hoàn chỉnh được logic quản lý state trong ứng dụng của bạn được. Nhận ra được vấn đề đó (theo quan điểm cá nhân của mình thì cũng 1 phần từ Hooks như nhắc đến đầu bài, ít nhất về mặt thời gian), team Redux đã giới thiệu RTK giúp chúng ta việc code redux nhanh hơn, gọn hơn và hoàn chỉnh theo 1 quy chuẩn thống nhất hơn.

Lưu ý các bạn 1 chút, nếu bạn đã nắm được Redux cơ bản, hiểu rõ các khái niệm về actions, reducer, store rồi thì việc tiếp cận RTK như là 1 cách tự nhiên, 1 bước cải tiến của bạn. Nhưng nếu bạn chưa biết hay làm qua Redux, mình khuyên nên khoan vội tìm hiểu RTK, hãy quay lại đọc Redux core như 1 kiến thức nền trước.

Trong bài hôm nay mình sẽ chỉ tập trung phân tích và so sánh cách triển khai code của RTK so với Redux trước đây để bạn hiểu hơn lí do nó được tạo ra. Trong cách bài viết theo mình sẽ giới thiệu chi tiết hơn cách cài đặt, triển khai và đi sâu vào các thành phần trong RTK như: createSlice, createAsyncThunk, createSelector, RTK Query, …

Đầu tiên, đây là cách các bạn tạo ra 1 store trong Redux, sẽ rất quen thuộc:

// store.js
import { createStore } from 'redux'

const INCREASEMENT = 'increasement'
const DECREASEMENT = 'decreasement'

// actions
export const increasement = () => {{ type: INCREASEMENT })
export const decreasement = () => ({ type: DECREASEMENT })

const initialState = { count: 0 }

//reducer
function rootReducer(state = initialState, action) {
    switch (action.type) {
        case INCREASEMENT:
            return { count: state.count + 1 };
            break;
        case DECREASEMENT:
            return { count: state.count - 1 };
            break;
        default:
            return state
    }
}

const store = createStore(rootReducer)

export default store

Đây là ví dụ mặc định (template) của redux nên mình xin phép không giải thích code ở đây (nó cũng quá đơn giản mà). Có 1 vài vấn đề ở đây:

OK chúng ta bắt đầu viết qua RTK.

Bước 1 là khai báo store

import { configureStore } from '@reduxjs/toolkit';

const store = configureStore({
  reducer: rootReducer
})

Ở đây configureStore của RTK nhìn thì giống createStore, nhưng mặc định nó đã được thiết lập 1 số middleware sẵn (mình sẽ trình bày chi tiết ở các bài viết sau) cũng như cho phép sử dụng redux devtool để debug và theo dõi quá trình state thay đổi. Tiện sẵn luôn đúng không, thay vì như cũ sẽ phải viết đoạn code đại loại như này:

import { createStore, applyMiddleware, compose } from "redux";
import rootReducer from "../reducers/index";
import { forbiddenWordsMiddleware } from "../middleware";
import thunk from "redux-thunk";

const storeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;

const store = createStore(
  rootReducer,
  storeEnhancers(applyMiddleware(forbiddenWordsMiddleware, thunk))
);

export default store;

Bước 2 là tạo action

import { createAction } from '@reduxjs/toolkit';

const increment = createAction('INCREMENT')

console.log(increment.type)
// "INCREMENT"

Thay vì 2 dòng code thì giờ gộp thành 1 dòng và lúc nào cũng trả về field type luôn, đỡ mất công viết lại.

Bước 3 là tạo reducer

import {createReducer} from '@reduxjs/toolkit'

const counter = createReducer({ count: 0 }, {
  [increment]: state => ({ count: state.count + 1 }),
  [decrement]: state => ({ count: state.count - 1 })
}

Ở đây logic chúng ta viết trông nó sẽ trực quan hơn, dạng key – value sẽ đơn giản và ngắn gọn hơn so với cách viết thuần.

Cuối cùng thì tổng hợp lại code, RTK sẽ viết chung lại như sau:

// store.js
import { configureStore, createAction, createReducer } from '@reduxjs/toolkit';

// actions
const increasement = createAction('increasement')
const decreasement = createAction('decreasement')

const initialState = { count: 0 }

function rootReducer = createReducer(initialState, {
    [increasement]: state => ({ count: state.count + 1 })
    [decreasement]: state => ({ count: state.count - 1 })
})

const store = configureStore({
    reducer: rootReducer
})

export default store

Gọn hơn và nhìn có vẻ chuyên nghiệp hơn đúng không các bạn. Tất nhiên là logic vẫn vậy, luồng tư duy vẫn vậy, nhưng các bạn sẽ giảm được sai sót khi gõ code, giảm các đoạn code mẫu lặp lại kha khá, nhìn cũng sướng mắt nữa.

Bài hôm nay đến đây thôi nhé, mình sẽ viết thêm về RTK sau vì còn nhiều cái hay ho, các APIs khác mà RTK cung cấp nữa. Cảm ơn mọi người

From Anyway with Love

Exit mobile version