Bộ công cụ Redux – Cấu trúc Redux của Refactor

Tram Ho

Mở đầu

Bài viết này mình viết với mục đích giới thiệu một concept thiết kế khác cho phần redux trong các ứng dụng được xây dựng bằng reactjs. Với kiến trúc thiết kế cấu trúc cũ, Redux cũng đã phần nào cải thiện rõ rệt việc cấu trúc các file. Tuy nhiên đối với mình, mình vẫn thấy chúng có một số nhược điểm như:

Với kiến trúc cũ sẽ tồn tại 2 folder chính cho reducer logic là reducers/index.js và action creators là actions/index.js.

Những ứng dụng lớn mình thường chia các file reducer và action tương ứng với nhau thành ra sẽ gặp vấn đề là mỗi lần thêm hay sửa một function trong actions lại phải lọ mọ sang bên reducers để định nghĩa hoặc sửa đổi => khá tốn effort . Chưa kể đến việc khi app lớn dần việc các file trong reducers ngày một nhiều, khi đấy việc tìm kiếm file cần sửa đổi trong một list dài ngoằng cũng khá tốn time

=> Do đó Redux toolkit đem đến một luồng gió mới để xử lý vấn đề tưởng chừng nhỏ bé nhưng lại thường là nguyên nhân tăng số lượng dòng code cũng như thời gian phát triển phần mềm lên khá nhiều.

Bài viết này mình sẽ hướng dẫn các bạn cách sử dụng redux toolkit bằng cách convert một app từ redux thường sang sử dụng redux toolkit.

Chuẩn bị

  • Đầu tiên thì chắc chắn bạn đã phải nắm được kiến thức về Redux và Reactjs
  • Chuẩn bị resource thực hành: Mình sẽ dùng sample kinh điển có sẵn của redux là todos app

Về cơ bản thì giao diện của trang web khá đơn giản, bên cạnh đó với app này thì cũng không có side effect do đó cũng không phải bận tâm đến vấn đề middleware sẽ không phải bận tâm lắm. Ở trong bài tiếp theo mình sẽ hướng dẫn các bạn tích hợp middleware vào.

Ok, khá ổn, trước khi bắt đầu code thì chúng ta thêm một file jsconfig.json để import các package tiện hơn :

Thực hành

Tiếp theo là các bước để convert một ứng dụng từ sử dụng redux thuần sang sử dụng redux toolkit

Install package và configureStore

Đầu tiên phải install package toolkit đã:

Khởi tạo Store bằng bằng configureStore
Sửa đổi lại một chút ở src/index.js, việc khởi tạo store chúng ta sẽ dùng hàm configureStore của package redux toolkit thay vì createStore của redux. Hàm này nhận params đầu vào là một object có key là reducer

Khởi tạo Slice

Đây chính là phần chính mà redux toolkit mang đến, cũng là một định nghĩa mởi. Trong phần này chúng ta sẽ cùng tìm hiểu định nghĩa và cách implement vào ứng dụng hiện tại.

Understanding Slices

Về cơ bản thì như phần đầu đã nói, redux toolkit được sử dụng nhằm để kết hợp giữa actions và reducers lại với nhau và đó chính là nhiệm vụ của slice và được thực thi bằng hàm createSlice. Thực chất trong phần lỗi thì nó cũng có các hàm createReducercreateAction, có thể để phục vụ những ai muốn dùng redux toolkit nhưng lại thích thiết kế cũ (hmmm) . Tuy nhiên chúng ta chỉ cần quan tâm đến createSlice, hàm này thực chất chính là kết hợp 2 hàm createReducercreateAction.

Giải thích một chút kĩ hơn thì các bạn có thể nhìn file root reducer:

Trong đây chúng ta dùng hàm combineReducers để gộp các file reducer con lại thành 1 root reducer, chúng ta có thể tạm hiểu các file nhỏ đấy sẽ được gọi là một slice, tuy nhiên để thành slice thì chúng sẽ phải chưa thêm các function để update lại các state của chúng.

Convert to Slices

Đầu tiên chúng ta sẽ băt đầu từ file reducers/todos.js:

Nhiệm vụ của file này sẽ là:

  • Thêm todo vào list khi người dùng gọi ‘ADD_TODO’
  • Đồi trạng thái của todo

Chúng ta sẽ tạo một folder features dành riêng cho các Slice, như vậy todos sẽ có cấu trúc file /features/todos/todosSlice.js :

Nhìn qua có thể nhận thấy rằng đây chính là bản nâng cấp của file reducers/todos.js, tại đây chúng ta có thêm object reducers dường như chứa cả các action tương ứng với phần logic thay đổi state => giảm đươc từ 2 file trở thành 1 file duy nhất.

Như vậy createSlice sẽ nhận 3 đối số :

  • name: Đây sẽ coi như là tiền tố để phân chia các slice để sau này dispatch các action dễ dàng hơn
  • initialState: Phần này tương tự như kiến trúc cũ, là phần các state khởi tạo của redux
  • reducers: Một object mà mỗi key giống như là một action, các action này sẽ kích hoạt khi chúng được dispatch type tương ứng (Nhìn ban đầu sẽ giống như là các case reducers trong switch của kiến trúc cũ)

Có thể hiểu rằng addTodo case reducer sẽ được kích hoạt khi mà action với type ‘todos/addTodo’ được kích hoạt

Nếu các bạn để ý thì chúng ta đã mất đi case defaults , case này sẽ trả về state hiên tại, chúng không mất đi mà được createSlice tự động handle vào.

Sử dụng Todos Slice

Đầu tiên là phải sửa lại phần root reducer reducers/index.js :

Tiếp theo sẽ phải update lại function addTodo được gọi ở component containers/AddTodo.js, ở đây hàm vẫn gọi đến action cũ, chúng ta sẽ sửa lại như sau :

Tiêp theo cũng phải sửa lại một chút cho case toggleTodo ở VisibleTodoList.js

Creating and Using Filter Slice

Tương tự như todos thì chúng ta còn một slice nữa cần chuyển đổi chính là visibilityFilters.js :

Sửa lại rootReducer:

Tiếp theo để hiển thị thì chúng ta phải sửa đổi lại ở UI

  • FilterLink.js

  • Link.js

Cleanup

Như vậy việc chuyển đổi đã loading đến 99%, việc tiép theo của chúng ta là bỏ đi nhưng folder thừa thãi. Và đây sẽ là danh sách nhưng folder sẽ bị loại bỏ :

  • actions/index.js
  • reducers/todos.js
  • reducers/visibilityFilter.js

Cấu trúc cuối sẽ như sau :

/src

  • /components
    • App.js
    • /features
      • /filters
        • FilterLink.js
        • filtersSlice.js
        • Footer.js
        • Link.js
      • /todos
        • AddTodo.js
        • Todo.js
        • TodoList.js
        • todosSlice.js
        • todosSlice.spec.js
        • VisibleTodoList.js
  • /reducers
    • index.js
  • index.js

Repo hoàn thiện các bạn có thể tham khảo : https://github.com/reduxjs/rtk-convert-todos-example

Kết luận

Như vậy phần trên mình đã giới thiệu một phương pháp để xây dựng ứng dụng reactjs có sử dụng đến redux. Với Redux toolkit thì số lượng code sẽ được mở rộng theo chiều dọc thay vì chiều ngang so với kiến trúc cũ. Bài viết phía trên ứng dụng cho một ứng dụng nhỏ chưa phải động đến middleware. Nhưng bài viết tiếp theo mình sẽ hướng dẫn các bạn cách để tích hợp với những ứng dụng phức tạp hơn.

Tham khảo

Bài viết phía trên mình thực nghiệm và tóm tăt lại, với những ai muốn tìm hiểu bản đầy đủ có thể đọc tại docs của react toolkit :
https://github.com/reduxjs/redux-toolkit/blob/master/docs/tutorials/intermediate-tutorial.md

Chia sẻ bài viết ngay

Nguồn bài viết : Viblo