Как правильно типизировать actions в редьюсере?
Пытаюсь разобраться с TS. Но что-то сложная задача для меня((. Помогите пожалуйста.
Редьюсер:
import { MoviesActionTypes, MoviesState, SearchAction } from '../types/movies';
const initialState: MoviesState = {
movies: [],
};
export function moviesReducer(state = initialState, action: SearchAction): MoviesState {
return action.type === MoviesActionTypes.SEARCH
? { ...state, movies: [...action.payload.films] }
: state;
}
Типы
export interface MoviesState {
movies: {}[];
}
export enum MoviesActionTypes {
SEARCH = 'SEARCH',
}
export interface SearchAction {
type: MoviesActionTypes.SEARCH;
payload: {};
}
Если я правильно понимаю, то мне нужно правильно указать тип в payload SearchAction...но как его указать? Туда будет приходить сложный объект. По ключу films я буду вытаскивать массив объектов и записывать их в стейт.
Ответы (1 шт):
Автор решения: xydope
→ Ссылка
Ответ на ваш вопрос подразумевает типизацию не state, а actions
Конкретно в вашем примере, вам нужно указать тип payload для searchAction
export interface SearchAction {
type: MoviesActionTypes.SEARCH;
payload: {
files: укажите тип files
};
}
более подробный пример на несколько разных action пример в codeSandBox
очень полезный видеоматериал по типизации, в том числе по редюсерам.
Полезная статья по выведению action type
type MoviesState = {
movies: string[]; //стринг, чтобы обозначить, что у нас просто массив названий фильмов, в целом, это пока не важно.
};
const initialState: MoviesState = {
movies: []
};
enum actionsName {
byActor,
byMovie,
byYear
}
type SearchByActor = {
type: actionsName.byActor;
payload: { actorName: string };
};
type SearchByYear = {
type: actionsName.byYear;
payload: { year: number };
};
type SearchByMovie = {
type: actionsName.byMovie;
payload: { movieName: string };
};
type SearchActions = SearchByActor | SearchByYear | SearchByMovie;
function moviesReducer(state = initialState, action: SearchActions) {
//редюсер ничего не делает, просто возвращает стейт
switch (action.type) {
case actionsName.byActor:
action.payload.actorName;
return state;
case actionsName.byYear:
action.payload.year;
return state;
case actionsName.byMovie:
action.payload.movieName;
return state;
default:
return state;
}
}