本人在写reducer中的action类的时候发现一些问题。为啥我的类型检查没有,过不了。后面实现了改功能,特在此记一笔。好记性不如烂笔头。
效果
我们就是要实现一个类似上图的效果,在每一个type中,action的类型是不一样。实现方式看下面的成功案例
成功案例
实现的业务场景,我想实现一个用户管理的功能,可以新增用户,删除,修改用户等。
每一个功能都是独立的并且所需要的参数是不一样的,所以做了以下类型检查。
公共类型
// common.ts // 公共类型
// 枚举每一个type类型。我是使用的枚举类型
export enum EUserListActionTypes {
'add' = 'add',
'del' = 'del',
'upa' = 'upa',
'setMore' = 'setMore'
}
/**
* 每一个用户的对象类型
*/
export interface IUserObj {
id: string,
name: string,
age?: number
}
/**
* 修改用户的类型,id必选,其他的参数可选
*/
export type updateUser = { id: string } & Partial<IUserObj>
/**
* 整个state的类型,里面包含一个用户列表
*/
export type userList = {
userList: IUserObj[]
}
/**
* 公共的action类型,一个泛型,必须包含两个属性,一个type,一个payload
*/
interface Action<T extends string, P> {
type: T,
payload: P
}
// 新增用户的action传值函数的返回值
export type addAction = Action<EUserListActionTypes.add, IUserObj>
// 修改用户的action传值函数的返回值
export type upaAction = Action<EUserListActionTypes.upa, updateUser>
// 删除用户的action传值函数的返回值
export type delAction = Action<EUserListActionTypes.del, Extract<{ id: string },updateUser> >
// 设置用户列表的action传值函数的返回值
export type setMoreAction = Action<EUserListActionTypes.setMore, IUserObj[]>
// 对于reducer的action的联合类型
export type ActionType = addAction | upaAction | delAction | setMoreAction
复制代码
action
类型写好了了后,写action创造函数。如下:
import { addAction, delAction, EUserListActionTypes, IUserObj, setMoreAction, upaAction, updateUser, userList } from "../types/common";
/**
* create an add userList action
* @param payload
* @returns
*/
export const createAddUserList = (payload: IUserObj): addAction => ({
type: EUserListActionTypes.add,
payload
})
/**
* create a update userList action
* @param payload
* @returns
*/
export const createUpdateUserList = (payload: updateUser): upaAction => ({
type: EUserListActionTypes.upa,
payload
})
/**
* create a delete userList action by id
* @param payload
* @returns
*/
export const createDelUserList = (payload: { id: string }): delAction => ({
type: EUserListActionTypes.del,
payload
})
/**
* set more data in userList
* @param payload
* @returns
*/
export const createSetMoreUserList = (payload: IUserObj[]): setMoreAction => ({
type: EUserListActionTypes.setMore,
payload
})
复制代码
最后写reducer
import { ActionType, EUserListActionTypes, userList } from "../types/common"
const initialState: userList = {
userList: [
{ id: '1', name: 'cll', age: 12 },
{ id: '2', name: 'twinkle', age: 13 },
]
}
/**
* userList reducer
*/
export default (state: userList = initialState, action: ActionType) => {
switch (action.type) {
case EUserListActionTypes.add:
return ({ userList: [...state.userList, action.payload] })
case EUserListActionTypes.upa:
return state.userList.map(p => p.id === action.payload.id ? { ...p, ...action.payload } : p)
case EUserListActionTypes.del:
return state.userList.filter(f => f.id !== action.payload.id)
case EUserListActionTypes.setMore:
return ({ userList: [...state.userList, ...action.payload] })
default:
return state
}
}
复制代码
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END