首頁 > web前端 > js教程 > Redux 工具包:建立 Thunk 函數

Redux 工具包:建立 Thunk 函數

Susan Sarandon
發布: 2024-12-23 13:39:05
原創
478 人瀏覽過

Redux Toolkit: Creating Thunk Functions

什麼是 Thunk?

在程式設計中,thunk 一詞指的是執行延遲工作的程式碼部分,例如 JavaScript 中的非同步函數。

Redux 儲存本身不處理非同步邏輯。它只知道如何:

  1. 同步調度動作。
  2. 透過減速器更新狀態。
  3. 通知 UI 有關狀態變更的資訊。

但是等等,如果是這樣的話,我們如何呼叫 API 並根據它們的回應更新狀態,這通常需要時間?我們該如何處理?

這就是 thunk 函數的用武之地。

什麼是 Thunk 函數?

thunk 函數是為處理非同步邏輯(例如呼叫 API)而建立的函數。它需要兩個參數dispatch和getState來調度動作,並在需要時存取當前狀態。

const getAllUsers = () => {
  return async (dispatch, getState) => {
    dispatch(fetingAllUsers());
    try {
      const users = await getUsers();
      dispatch(userUpdated(users));
    } catch (err) {
      dispatch(logError(err))
    }
  }
}
登入後複製
登入後複製

傳回的函數是 thunk 函數,getAllUsers 在本例中稱為 thunk 動作建立者,它將像這樣調度:

dispatch(getAllUsers())
登入後複製

如果需要,可以使用 thunk 函數中使用的參數來調度 thunk 動作建立者。

使用 createAsyncThunk 建立 Thunk

Redux Toolkit 提供了 createAsyncThunk API 來輕鬆產生 thunk:

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

export const fetchUserById = createAsyncThunk(
  'user/fetchUserById',
  async (userId) => {
    const user = await someHttpRequest(userId);
    return user;
  }
);
登入後複製

fetchUserById 是這裡建立的 thunk 函數。 createAsyncThunk 採用兩個參數:

  • 第一個參數是用於產生的操作類型的字串前綴(例如 user/fetchUserById/pending、user/fetchUserById/fulfilled 或 user/fetchUserById/rejected)。
  • 第二個參數是「有效負載創建者」函數。它應該傳回一個包含所需資料或錯誤的 Promise。

為什麼要使用createAsyncThunk?

除了讓您為 API 呼叫建立 thunk 函數之外,createAsyncThunk 還會自動排程操作來追蹤 API 請求的狀態:

  • 待處理:請求正在進行中。
  • fulmeded:請求成功。
  • 被拒絕:請求失敗。

這真的很有用。例如,當狀態處於掛起狀態時,我們可以在 UI 中顯示載入程序,並讓使用者知道正在發生某些事情。

在切片中使用 thunk

現在我們已經建立了 fetchUserById thunk,我們可以使用 userSlice 中的 extraReducers 欄位來處理狀態變更:

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

const initialState = {
  user: null,
  status: 'idle', // 'idle' | 'pending' | 'succeeded' | 'failed'
  error: null,
};

export const userSlice = createSlice({
  name: 'user',
  initialState,
  reducers: {
    usernameUpdated: (state, action) => {
      state.user.username = action.payload;
    },
    emailUpdated: (state, action) => {
      state.user.email = action.payload;
    },
    userDataCleared: (state) => {
      state.user = null;
      state.status = 'idle';
    },
  },
  extraReducers: (builder) => {
    builder
      .addCase(fetchUserById.pending, (state) => {
        state.status = 'pending';
      })
      .addCase(fetchUserById.fulfilled, (state, action) => {
        state.status = 'succeeded';
        state.user = action.payload;
      })
      .addCase(fetchUserById.rejected, (state, action) => {
        state.status = 'failed';
        state.error = action.error.message || 'Something went wrong.';
      });
  },
});

export const { usernameUpdated, emailUpdated, userDataCleared } = userSlice.actions;

// Selector for the status to use in the application's components
export const selectStatus = (state) => state.user.status;
登入後複製

createAsyncThunk 條件

如果我們想在呼叫API之前檢查一些條件怎麼辦?例如,如果狀態已經處於待處理狀態,我們不想呼叫它兩次。在這種情況下,我們可以使用 createAsyncThunk 接受的第三個參數來寫入條件。

const getAllUsers = () => {
  return async (dispatch, getState) => {
    dispatch(fetingAllUsers());
    try {
      const users = await getUsers();
      dispatch(userUpdated(users));
    } catch (err) {
      dispatch(logError(err))
    }
  }
}
登入後複製
登入後複製

要了解如何將 Typescript 與 thunk 函數結合使用,請閱讀類型檢查 Redux Thunk。

以上是Redux 工具包:建立 Thunk 函數的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:dev.to
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板