createSlice
这是一个接受初始状态、一个包含 reducer 函数的对象和一个 "slice 名称" 的函数, 并自动生成与 reducer 和状态对应的 action 创建器和 action 类型。
这个 API 是编写 Redux 逻辑的标准方法。
在内部,它使用 createAction
和 createReducer
,所以
你也可以使用 Immer 来编写 "变异" 的不可变更新:
import { createSlice } from '@reduxjs/toolkit'
import type { PayloadAction } from '@reduxjs/toolkit'
interface CounterState {
value: number
}
const initialState = { value: 0 } satisfies CounterState as CounterState
const counterSlice = createSlice({
name: 'counter',
initialState,
reducers: {
increment(state) {
state.value++
},
decrement(state) {
state.value--
},
incrementByAmount(state, action: PayloadAction<number>) {
state.value += action.payload
},
},
})
export const { increment, decrement, incrementByAmount } = counterSlice.actions
export default counterSlice.reducer
参数
createSlice
接受一个单一的配置对象参数,具有以下选项:
function createSlice({
// 一个用于 action 类型的名称
name: string,
// reducer 的初 始状态
initialState: State,
// 一个包含 "case reducers" 的对象。键名将用于生成 actions。
reducers: Record<string, ReducerFunction | ReducerAndPrepareObject>,
// 一个用于添加更多 reducers 的 "builder callback" 函数
extraReducers?: (builder: ActionReducerMapBuilder<State>) => void,
// slice reducer 的位置偏好,由 `combineSlices` 和 `slice.selectors` 使用。默认为 `name`。
reducerPath?: string,
// 一个接收 slice 的状态作为其第一个参数的 selectors 对象。
selectors?: Record<string, (sliceState: State, ...args: any[]) => any>,
})
initialState
这个 slice 的状态的初始值。
这也可以是一个 "lazy initializer" 函数,当被调用时应返回一个初始状态值。当 reducer 被调用并且其状态值为 undefined
时,将使用这个函数,这主要用于像从 localStorage
读取初始状态这样的情况。
name
这个 slice 的状态的字符串名称。生成的 action 类型常量将使用这个作为前缀。
reducers
一个包含 Redux "case reducer" 函数的对象(旨在处理特定 action 类型的函数,相当于 switch 中的单个 case 语句)。
对象中的键将用于生成字符串 action 类型常量,当它们被派发时,这些将显示在 Redux DevTools Extension 中。此外,如果应用的其他部分恰好派发了具有完全相同类型字符串的 action,将运行相应的 reducer。因此,你应该给函数取描述性的名称。
这个对象将传递给 createReducer
,所以 reducers 可以安全地 "变异" 它们被给予的状态。
import { createSlice } from '@reduxjs/toolkit'
const counterSlice = createSlice({
name: 'counter',
initialState: 0,
reducers: {
increment: (state) => state + 1,
},
})
// 将处理 action 类型 `'counter/increment'`
自定义生成的 Action 创建器
如果你需要通过 prepare callback
自定义 action 创建器的 payload 值的创建,那么 reducers
参数对象的相应字段的值应该是一个对象而不是一个函数。这个对象必须包含两个属性:reducer
和 prepare
。reducer
字段的值应该是 case reducer 函数,而 prepare
字段的值应该是 prepare callback 函数:
import { createSlice, nanoid } from '@reduxjs/toolkit'
import type { PayloadAction } from '@reduxjs/toolkit'
interface Item {
id: string
text: string
}
const todosSlice = createSlice({
name: 'todos',
initialState: [] as Item[],
reducers: {
addTodo: {
reducer: (state, action: PayloadAction<Item>) => {
state.push(action.payload)
},
prepare: (text: string) => {
const id = nanoid()
return { payload: { id, text } }
},
},
},
})
reducers
"creator callback" 符号
另外,reducers
字段可以是一个接收 "create" 对象的回调。
这样做的主要好处是你可以在你的 slice 中创建 async thunks(尽管出于 bundle 大小的原因,你需要一些设置来实现这一点)。对于 prepared reducers,类型也稍微简化了。
import { createSlice, nanoid } from '@reduxjs/toolkit'
interface Item {
id: string
text: string
}
interface TodoState {
loading: boolean
todos: Item[]
}
const todosSlice = createSlice({
name: 'todos',
initialState: {
loading: false,
todos: [],
} satisfies TodoState as TodoState,
reducers: (create) => ({
deleteTodo: create.reducer<number>((state, action) => {
state.todos.splice(action.payload, 1)
}),
addTodo: create.preparedReducer(
(text: string) => {
const id = nanoid()
return { payload: { id, text } }
},
// action 类型是从 prepare 回调中推断出来的
(state, action) => {
state.todos.push(action.payload)
},
),
fetchTodo: create.asyncThunk(
async (id: string, thunkApi) => {
const res = await fetch(`myApi/todos?id=${id}`)
return (await res.json()) as Item
},
{
pending: (state) => {
state.loading = true
},
rejected: (state, action) => {
state.loading = false
},
fulfilled: (state, action) => {
state.loading = false
state.todos.push(action.payload)
},
},
),
}),
})
export const { addTodo, deleteTodo, fetchTodo } = todosSlice.actions
创建方法
create.reducer
一个标准的 slice case reducer。
参数
- reducer 要使用的 slice case reducer。
create.reducer<Todo>((state, action) => {
state.todos.push(action.payload)
})
create.preparedReducer
一个预处理的 reducer,用于自定义 action creator。
参数
- prepareAction
prepare 回调
。 - reducer 要使用的 slice case reducer。
传递给 case reducer 的 action 将从 prepare 回调的返回值中推断出来。
create.preparedReducer(
(text: string) => {
const id = nanoid()
return { payload: { id, text } }
},
(state, action) => {
state.todos.push(action.payload)
},
)