Answer the question
In order to leave comments, you need to log in
How to type useReducer and are there generally cleaner options?
I'm experimenting with useReducer and ran into this problem. For example, there is an array of some records. You need to get it, assign it to the component state, and then manually add new entries and delete them. The question is how to properly type this whole thing?
I sketched out such an option , but a few things confuse me:
First, the explicit assignment of the three possible types in payload:
type ActionType = {
type: ActionPointsType;
payload: AlbumType | AlbumType[] | number;
};
switch (action.type) {
case ActionPoints.SET_ALBUMS:
return action.payload as AlbumType[];
case ActionPoints.ADD_ALBUM:
return [...state, action.payload] as AlbumType[];
case ActionPoints.REMOVE_ALBUM:
return state.filter((album) => album.id !== action.payload);
default:
return state;
}
type ActionType<T = any> = {
type: ActionPointsType
payload: T
};
// ...
const addNewAlbum = (event: React.FormEvent) => {
event.preventDefault();
const action: ActionType<AlbumType> = {
type: ActionPoints.ADD_ALBUM,
payload: {
id: albums.length + 1,
title: newAlbum
}
}
dispatch(action);
}
Answer the question
In order to leave comments, you need to log in
type AlbumType = {
id: number;
title: string;
};
enum ActionPoints {
SET_ALBUMS = "SET_ALBUMS",
ADD_ALBUM = "ADD_ALBUM",
REMOVE_ALBUM = "REMOVE_ALBUM"
}
type ActionType = {
type: ActionPoints.SET_ALBUMS;
payload: AlbumType[];
} | {
type: ActionPoints.ADD_ALBUM;
payload: AlbumType;
} | {
type: ActionPoints.REMOVE_ALBUM;
payload: number;
};
const reducer = (state: AlbumType[], action: ActionType) => {
switch (action.type) {
case ActionPoints.SET_ALBUMS:
return action.payload;
case ActionPoints.ADD_ALBUM:
return [...state, action.payload];
case ActionPoints.REMOVE_ALBUM:
return state.filter((album) => album.id !== action.payload);
default:
return state;
}
};
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question