Thuật ngữ “thunk” ở trong lập trình có nghĩa là đoạn code gây ra một số tác vụ trì hoãn.
Trong Redux, thunk là một hàm cho phép bổ sung các logic tách biệt với UI layer. Các logic này có thể là các side effect (chẳng hạn như fetch data), dispatch nhiều action hoặc truy cập đến state của store.
Để sử dụng thunk, ta cần thêm “redux-thunk” middleware vào store. Nếu sử dụng Redux Toolkit thì không cần.
Writing Thunks
Một thunk function sẽ nhận vào hai đối số là phương thức dispatch
và getState
.
Ví dụ:
Logic ở trong thunk có thể là đồng bộ hoặc bất đồng bộ và ta có thể gọi sử dụng dispatch
hoặc getState
bất cứ lúc nào.
Chúng ta cũng có thể dùng một hàm để tạo ra thunk. Ta gọi hàm đó là thunk action creator, ví dụ:
Thunk action creator và thunk cũng có thể là arrow function:
Thunk sẽ được dispatch thông qua thunk action creator, tương tự như khi ta dispatch action bằng cách truyền vào action creator:
Minh họa quá trình gọi API khi sử dụng thunk:
Tip
Thunk action creator và thunk thường được viết ở trong file chứa slice.
Thunk Usage Patterns
Dispatching Actions
Chúng ta có thể dùng thunk để dispatch nhiều action cùng một lúc hoặc thậm chí là dispatch các thunk khác.
Ví dụ bên dưới dispatch một action và một thunk:
Accessing State
Không giống như các component, thunk có quyền truy cập đến phương thức getState
và có thể gọi sử dụng phương thức này bất cứ lúc nào. Tính năng này hữu ích khi ta cần xử lý một số logic dựa trên state hiện tại, ví dụ:
Do state được cập nhật ngay lập tức nên ta có thể gọi getState
sau khi dispatch để lấy ra state mới:
Trong trường hợp ta cần lấy ra state của nhiều slice khác nhau, ta cũng có thể sử dụng thunk:
Async Logic and Side Effects
Khi thực hiện gửi request ở trong thunk, ta cần dispatch các action trước và sau khi request được xử lý nhằm kiểm soát loading state của request đó.
Thường thì ta sẽ dispatch “pending” action trước khi gửi request. Nếu request thành công thì ta sẽ dispatch “fulfilled” action. Còn nếu request thất bại thì ta sẽ dispatch “rejected” action.
Ví dụ:
Using createAsyncThunk
Thay vì tạo ra 3 action cho 3 trạng thái của request một cách thủ công và dispatch chúng ở trong thunk, ta có thể sử dụng phương thức createAsyncThunk
của Redux Toolkit để tự động sinh ra các action cũng như là lược bỏ các dispatch ở trong thunk function.
Phương thức này nhận vào hai đối số:
- Một action type string dùng để tạo các action type tương ứng với 3 trạng thái của request (
pending
,fulfilled
vàrejected
) - Một “payload creation callback” chứa các đoạn code bất đồng bộ và trả về một Promise.
Ví dụ:
Giá trị trả về của createAsyncThunk
là một async thunk.
Payload creation callback cũng nhận vào hai đối số:
arg
: là đối số truyền vào async thunk khi dispatch.thunkAPI
: là một đối tượng gồm nhiều thuộc tính. Trong số đó có phương thứcrejectWithValue
giúp trả về một rejected response.
Ví dụ:
Seealso
Thêm vào các reducer cho từng trạng thái của request khi tạo slice như sau:
Lưu ý là ta cần phải export slice reducer để thêm vào store.
Dispatch async thunk ở trong component như sau:
Cũng có thể dispatch async thunk thông qua store: