跳到主要內容

autoBatchEnhancer

Redux store enhancer,會尋找一或多個「低優先權」的已發送 action,並排隊一個 callback,在延遲後執行訂閱者通知。然後,當排隊的 callback 執行,或當下一個「正常優先權」的 action 已發送時,通知訂閱者,以先發生的為準。

基本用法

import {
createSlice,
configureStore,
autoBatchEnhancer,
prepareAutoBatched,
} from '@reduxjs/toolkit'

interface CounterState {
value: number
}

const counterSlice = createSlice({
name: 'counter',
initialState: { value: 0 } satisfies CounterState as CounterState,
reducers: {
incrementBatched: {
// Batched, low-priority
reducer(state) {
state.value += 1
},
// Use the `prepareAutoBatched` utility to automatically
// add the `action.meta[SHOULD_AUTOBATCH]` field the enhancer needs
prepare: prepareAutoBatched<void>(),
},
// Not batched, normal priority
decrementUnbatched(state) {
state.value -= 1
},
},
})
const { incrementBatched, decrementUnbatched } = counterSlice.actions

// includes batch enhancer by default, as of RTK 2.0
const store = configureStore({
reducer: counterSlice.reducer,
})

API

autoBatchEnhancer

autoBatchEnhancer 簽章
export type SHOULD_AUTOBATCH = string
type AutoBatchOptions =
| { type: 'tick' }
| { type: 'timer'; timeout: number }
| { type: 'raf' }
| { type: 'callback'; queueNotification: (notify: () => void) => void }

export type autoBatchEnhancer = (options?: AutoBatchOptions) => StoreEnhancer
提示

自 RTK 2.0 起,在呼叫 configureStore 時,autoBatchEnhancer 預設會包含在內。

這表示要設定它,你應該傳遞一個接收 getDefaultEnhancers 的回呼,並使用你想要的設定呼叫它。

使用 getDefaultEnhancers 設定 autoBatchEnhancer
import { configureStore } from '@reduxjs/toolkit'

const store = configureStore({
reducer: () => 0,
enhancers: (getDefaultEnhancers) =>
getDefaultEnhancers({
autoBatch: { type: 'tick' },
}),
})

建立 autobatch 儲存體增強器的全新執行個體。

任何標記為 action.meta[SHOULD_AUTOBATCH] = true 的動作都會被視為「低優先順序」,而且會排隊一個通知回呼。增強器會延遲通知訂閱者,直到

  • 排隊的回呼執行並觸發通知
  • 在同一個時間點派送一個「正常優先順序」的動作(任何沒有 action.meta[SHOULD_AUTOBATCH] = true 的動作)

autoBatchEnhancer 接受選項來設定通知回呼的排隊方式

  • {type: 'raf'}:使用 requestAnimationFrame 排隊(預設)
  • {type: 'tick'}:使用 queueMicrotask 排隊
  • {type: 'timer', timeout: number}:使用 setTimeout 排隊
  • {type: 'callback', queueNotification: (notify: () => void) => void}:讓你提供自己的回呼,例如防彈或限制函式

預設行為是使用 requestAnimationFrame 排隊通知。

SHOULD_AUTOBATCH 值應為不透明的 - 目前它是一個字串以簡化起見,但未來可能會是 Symbol

prepareAutoBatched

prepareAutoBatched 簽章
type prepareAutoBatched = <T>() => (payload: T) => { payload: T; meta: unknown }

建立一個接受 payload 值的函式,並傳回一個具有 {payload, meta: {[SHOULD_AUTOBATCH]: true}} 的物件。這應與 RTK 的 createSlice 及其「prepare 回呼」語法一起使用

createSlice({
name: 'todos',
initialState,
reducers: {
todoAdded: {
reducer(state, action: PayloadAction<Todo>) {
state.push(action.payload)
},
prepare: prepareAutoBatched<Todo>(),
},
},
})

批次處理方法和背景

文章 Redux 批次處理技術比較 說明了四種不同的「批次處理 Redux 動作/派送」方法

  • 接受嵌在一個真實動作中的多個動作,並一起迭代它們的高階簡約器
  • 包裝 dispatch 並限制通知回呼的增強器
  • 包裝 dispatch 以接受動作陣列的增強器
  • React 的 unstable_batchedUpdates(),它只將多個排隊的渲染器合併成一個,但不會影響訂閱者通知

這個增強器是「防抖」方法的變體,但有些不同。

它不是防抖所有訂閱者通知,而是觀察任何帶有特定 action.meta[SHOULD_AUTOBATCH]: true 欄位的動作。

當它看到帶有該欄位的動作時,它會排隊一個回呼。還原器會立即更新,但增強器不會立即通知訂閱者。如果連續傳送其他帶有相同欄位的動作,增強器將繼續通知訂閱者。然後,當排隊的回呼執行時,它會最終通知所有訂閱者,類似於 React 批次重新渲染的方式。

額外的不同也受到 React 將更新區分為「低優先級」和「立即」行為的啟發(例如,由 AJAX 要求排隊的渲染與由應同步處理的使用者輸入排隊的渲染)。

如果已傳送一些低優先級動作,並且通知微任務已排隊,然後傳送一個正常優先級動作(沒有欄位),增強器將繼續像往常一樣同步通知所有訂閱者,而不是在刻度結束時通知他們。

這允許 Redux 使用者有選擇地標記某些動作以進行有效的批次行為,使這純粹是逐動作選擇加入,同時為所有其他動作保留正常的通知行為。

RTK 查詢和批次處理

RTK 查詢已將其幾個主要的內部動作類型標記為可批次處理。透過將 autoBatchEnhancer 新增到儲存設定,它可以改善整體 UI 效能,特別是在渲染使用 RTKQ 查詢掛勾的大量元件清單時。