Redux Toolkit: Tìm hiểu createSlice

Bài viết được sự cho phép của tác giả Phạm Minh Khoa

Tiếp theo bài trước, mình sẽ giới thiệu chi tiết hơn các API cơ bản của Redux-Toolkit để chúng ta có thể tạo được 1 flow hoàn chỉnh của Redux.

Redux Module

Trong Redux, 1 module hoàn chỉnh bao gồm: Store, Actions và Reducer, thông thường các bạn sẽ chia viết từng phần trong các file riêng và cấu trúc folder sẽ dạng như dưới đây:

Redux Module

Với Redux Toolkit (RTK) thì tối giản hơn, tạo 1 module hoàn chỉnh bằng API createSlice.

  React Redux: Redux middleware là gì?

  Redux vận hành như thế nào

https://redux-toolkit.js.org/api/createSlice

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

const counterSlice = createSlice({
  name: 'counter',
  initialState: { count: 0 },
  reducers: {
    increment: state => state.count += 1,
    decrement: state => state.count -= 1
  }
})

export const { increment, decrement } = counterSlice.actions
export default counterSlice.reducer

Một số ưu điểm của cách viết này:

  • Không còn tạo riêng các file action, reducer, type
  • action types tự động sinh ra kèm tiền tố mặc định là trường name
  • Cú pháp hoàn chỉnh, ngắn gọn và theo 1 template logic nhất quán của redux

Tham khảo việc làm Back-end hấp dẫn trên TopDev

Thực tế dự án, các bạn có thể cần giải quyết 1 số case dispatch action phổ biến như lắng nghe 1 action chung nào đó của toàn bộ ứng dụng, trong trường hợp đó createSlice cung cấp 1 option extraReducers để giải quyết bài toán trên :

const otherAction = createAction('updateCounterByValue')
...
extraReducers: (builder) => {
      build.addCase(otherAction, (state, action) => {
             state.count += action.payload
      })
      .addDefaultCase((state, action) => {})
  }

hoặc
// có thể viết là [otherAction] hoặc otherAction.type
      [otherAction]: (state, action) => {
             state.count += action.payload
      }

Nếu 1 reducer lắng nghe nhiều action có cùng logic:

const isErrorAction = (action) => {
    return action.type.endsWith('FAIL')
}

const reducer = createReducer(initState, (builder) => {
    build
        .addMatcher(isErrorAction, (state, action) => {
            state.errors = action.payload
        })
        .addDefaultCase((state, action) => {})
})

Cấu trúc folder store với Redux Toolkit

Rõ ràng slice giúp Redux viết gọn và chuẩn hơn rất nhiều so với cách cũ, bao gồm cả code và cách tổ chức file.

Trong phần tới mình sẽ cùng tìm hiểu cách xử lý bất đồng bộ trong Redux Toolkit.

Cảm ơn các bạn!

Bài viết gốc được đăng tải tại: anywayblogs.com

Xem thêm:

Xem thêm Top Việc làm Developer trên TopDev