THis is my code:
import { Conversation } from "@/types/conversation";
import { PayloadAction, createSlice } from "@reduxjs/toolkit";
const initialState: Conversation | null = null;
export const conversationSlice = createSlice({
name: "conversation",
initialState,
reducers: {
setConversation: ( // type error
state: Conversation | null,
action: PayloadAction<Conversation>
) => {
state = action.payload;
return state;
},
},
});
// Action creators are generated for each case reducer function
export const { setConversation } = conversationSlice.actions;
export default conversationSlice.reducer;
THis is the error I am receiving:
Type '(state: Conversation | null, action: PayloadAction<Conversation>) => Conversation' is not assignable to type 'CaseReducer<null, { payload: any; type: string; }> | CaseReducerWithPrepare<null, PayloadAction<any, string, any, any>>'.
Type '(state: Conversation | null, action: PayloadAction<Conversation>) => Conversation' is not assignable to type 'CaseReducer<null, { payload: any; type: string; }>'.
Type 'Conversation' is not assignable to type 'void'.ts(2322)
I know that immer is used under the hood of createSlice
. WHen I remove return statement from setCOnversation
- error is gone but reducer does not work. If I leave it like that, reducer works (organization sets) but I have an error.
How to fix it ?
I have tried to get rid of return statement, but it brokes application in the other way. ALso read redux toolkit docs
Still getting an error:
import { Draft, PayloadAction, createSlice } from "@reduxjs/toolkit";
interface Conversation {
any_data: string[];
}
const initialState: Conversation | null = null;
export const conversationSlice = createSlice({
name: "conversation",
initialState,
reducers: {
setConversation: (
// type error
state: Draft<Conversation | null>,
action: PayloadAction<Conversation>
) => action.payload,
},
});
// Action creators are generated for each case reducer function
export const { setConversation } = conversationSlice.actions;
export default conversationSlice.reducer;
You cannot reassign state in RTK reducers, e.g. state = action.payload
is invalid. You can either mutate the draft state or return the new state value (never both).
I'd argue that the conversation
state should not be nullable. With nullable state the UI would need to first check that the state is defined, e.g. not null. I suggest dropping the nullable state and make the conversation state properties optional. The UI will then use a null-check on the conversation state property it accesses.
Consider the following rewrite:
import { PayloadAction, createSlice } from "@reduxjs/toolkit";
interface Conversation {
any_data?: string[];
}
const initialState: Conversation = {};
export const conversationSlice = createSlice({
name: "conversation",
initialState,
reducers: {
setConversation: (state, action: PayloadAction<Conversation>) => {
return action.payload;
},
},
});
export const { setConversation } = conversationSlice.actions;
export default conversationSlice.reducer;