快速创建Action
在Redux中Action实际上就是一个有着特定结构的普通Javascript对象。在习惯上,Action的基本类型就是{ type: string, payload: any }
。
在Redux使用到项目开发中以后,经历了一个首先定义大量Action Type字符串,然后过渡到利用Action构建函数根据需要动态的创建Action。例如以下示例所示。
const INCREASE = 'counter/increase';
function counterIncrease(amount: number) {
return {
type: INCREASE,
payload: amount
};
}
// 定义Action构建函数以后,就可以使用以下形式创建Action
const action = counterIncrease(1);
因为这种Action的结构形式和创建方法已经基本上得到了绝大多数Redux使用者的认可和习惯,所以Redux Toolkit根据这个Action的结构形式和创建方法,引入了一个能够快速创建Action的辅助函数createAction
。
利用createAction
这个辅助函数来重写上面的示例,就会使代码变得十分简练。
import { createAction } from '@reduxjs/toolkit';
// createAction创建的是一个生成器函数,返回的函数在执行以后才会返回一个Action生成函数。
const counterIncreaseAction = createAction<number | undefined>('counter/increase');
// 调用执行生成器函数可以生成一个Action,如果提供任何参数生成的Action就不会携带payload属性。
// 在这个示例中生成的action内容是 \{ type: 'counter/increase' \}
const counterIncrease = counterIncreaseAction();
// 传递一个参数来调用生成器函数可以生成一个带有payload属性的Action对象。
// 在这个示例中,action的内容是 \{ type: 'counter/increase', payload: 1 \}
const action = counterIncrease(1);
createAction
函数的函数签名是createAction(type, preparedAction?)
,所以除了可以直接指定一个type
参数来快速定义一个Action生成器函数以外,还可以通过传递一个自定义的Action准备函数来为默认生成的Action携带的内容。以下示例在之前示例的基础上为Action自定义了要携带的内容。
import { createAction } from '@reduxjs/toolkit';
const counterIncreaseAction = createAction('counter/increase', (amount: number, text: string) => ({
payload: {
amount,
message: text,
createdAt: new Date().getTime()
}
}));
// 调用这个生成器函数可以直接生成一个Action对象。
// 在这个示例中,action的内容是 \{ type: 'counter/increase', payload: \{ amount: 1, message: 'hello', createdAt: 1652523758732 \} \}
const increaseAction = counterIncreaseAction(1, 'Hello');
注意,createAction
所构建的Action只能使用字符串作为Action类型,不能创建非字符串类型的Action。任何传入的非字符串类型的Action类型值,都将被转换成字符串。
当具备了一些Action以后,就可以前进到定义Reducer的步骤了。