I have the following code to define a React Reducer function:
import { useReducer, Reducer } from 'react';
interface IArrowState {
ascending: [
{ time: boolean },
{ user: boolean }
]
}
type ArrowAction = {
type: string;
}
const Events: FC<IEventComponent> & {getLayout: (params: any) => void;} = () => {
const arrowInitialState: IArrowState = {
ascending: [
{ time: true },
{ user: true }
]
}
const arrowReducer: Reducer<IArrowState, ArrowAction> = (state, action) => {
switch (action.type) {
case 'time':
return state.ascending['time'] = !state.ascending['time'];
case 'user':
return state.ascending['user'] = !state.ascending['user'];
}
}
}
However I'm getting TS2322 Type A is not assignable to type B error on line
const arrowReducer: Reducer<IArrowState, ArrowAction>
:
Can someone explain what is going wrong here? Should I give a return type to Reducer<IArrowState, ArrowAction>
?
You didn't update the state correctly, you must do the immutable update for the state in the reducer function. See immutable-update-patterns
import type { Reducer } from 'react';
interface IArrowState {
ascending: [
{ time: boolean },
{ user: boolean }
]
}
type ArrowAction = {
type: string;
}
const arrowInitialState: IArrowState = {
ascending: [
{ time: true },
{ user: true }
]
}
const arrowReducer: Reducer<IArrowState, ArrowAction> = (state, action): IArrowState => {
const [time, user] = state.ascending;
switch (action.type) {
case 'time':
return {
...state,
ascending: [{ time: !time.time }, user]
}
case 'user':
return {
...state,
ascending: [time, { user: !user.user }]
}
default:
return state;
}
}
const nextArrowState = arrowReducer(arrowInitialState, { type: 'time' });
console.log('nextArrowState: ', nextArrowState);
TS Playground(Click "Run" to check the logs in right panel)