如何在redux typescript中使用多个有效载荷接口的减速机动作?



我有一个名为Messages的reducer,它将具有以下操作:

  1. GET_MESSAGES_START→它开始使用API加载10条最近的消息
  2. GET_MESSAGES_SUCCESS→使用API
  3. 完成10条最近消息的加载
  4. GET_MESSAGES_FAIL→API失败
  5. RESET_MESSAGE→删除特定用户的消息/收件箱
  6. GET_SOCKET_MESSAGE→从套接字获取消息

GET_MESSAGE_START,RESET_MESSAGE→有效载荷为{chatUser: "username"}

GET_MESSAGE_SUCCESS→有效载荷为{chatUser: "username",nextPage: 2,count: 22,messages:Array<InboxMessages>}

GET_MESSAGE_FAIL→有效载荷为{error:[Error]}

GET_SOCKET_MESSAGE→有效载荷为{chatUser: "username", message: <InboxMessages> }

界面


// For Reusing
export interface errorInterface{
error?:null|string|Array<string>|{[key:string]:any}
}
// For Reusing
export interface BaseLoadingInterface {
loading: boolean
}
// For Reusing
export interface NextPageInterface {
nextPage: number | null
}
export interface InboxMessages {
id: number,
user: userInterface,
receiver: userInterface,
message: string,
timestamp: Date,
thread: number,
attachment: any
}
export interface MessageInboxInterface extends BaseLoadingInterface, NextPageInterface{
user: string,
messages: Array<InboxMessages>,
count: number,
}

export interface MessageStateInterface extends errorInterface{
chatUser: string | null,
inbox: Array<MessageInboxInterface>
}

export interface MessagePayload {
chatUser: string,
nextPage: null | number,
count: number,
messages: Array<InboxMessages>
}
export interface MessageStartInterface {
type: typeof GET_MESSAGES_START | typeof RESET_MESSAGE,
payload:{
chatUser: string
}
}
export interface MessageSuccessInterface{
type: typeof GET_MESSAGES_SUCCESS,
payload:MessagePayload
}
export interface MessageFailInterface {
type: typeof GET_MESSAGES_FAIL,
payload: errorInterface
}
export interface SocketMessageInterface{
type: typeof GET_SOCKET_MESSAGE,
payload: InboxMessages
}
export type MessageAction = MessageStartInterface | MessageSuccessInterface | SocketMessageInterface

齿轮


const defaultMessagesState:MessageStateInterface = {
chatUser:null,
error:null,
inbox:[],
};

export const userChatMessageReducer = (state:MessageStateInterface=defaultMessagesState, action:MessageActionInterface) => {
const{type,payload}=action;
const chatUserInbox = state.inbox.filter(el => el.user === payload.chatUser);
const inbox = state.inbox.filter(el => el.user !== payload.chatUser);
switch (type) {
case GET_MESSAGES_START:
// Returns a updated User Inbox
getMessageStartInbox(state, payload)
return{
...state,
chatUser:payload.chatUser,
inbox: inbox
};
case GET_MESSAGES_SUCCESS:
// Returns a updated Inbox with messages
return {
...state,
inbox: [...inbox,getInboxMessage(state, payload)]
};
case GET_SOCKET_MESSAGE:
// Initiate New Message From Socket and returns new message
return {
...state,
inbox: [...inbox,newInboxObject(state, payload.message)]
};
case RESET_MESSAGE:
// Delete chat user's message
return {
...state,
inbox:[...inbox]
};
case GET_MESSAGES_FAIL:
return {
...state,
error: payload.error
};
default:
return state
}
};

但我得到错误,说,chatUser,消息,消息不在MessageActionInterface ->有效载荷类型。这些不是MessageActionInterface.payload的有效类型

在switch语句的分支中出现错误的原因是由于一个小的技术问题。当你在switch语句之外解构action对象时,Typescript会同时给typepayload赋值一个类型。它们现在有了自己的类型,所以Typescript不会考虑它们之间的关系。switch的每个case都细化了type的类型定义,但没有细化payload的类型定义。

解决方案很简单:不要重构action对象。使用switch (action.type),用action.payload替换对payload的引用。

还有一个潜在的问题,即在switch之外访问payload.chatUser以生成inbox。似乎不是所有的动作类型都有chatUser属性(InboxMessages中的user应该是chatUser吗?)。

我们可以使用保护'chatUser' in action.payload来有条件地访问chatUser,以确保该属性存在。如果没有,则返回null,并获得inbox的空数组。

const chatUser = ( 'chatUser' in action.payload ) ? action.payload.chatUser : null;
const inbox = state.inbox.filter(el => el.user !== chatUser);

相关内容

  • 没有找到相关文章

最新更新