Skip to content

Commit

Permalink
Add entity adapter to manage state JC-720
Browse files Browse the repository at this point in the history
  • Loading branch information
TebyakinaEkaterina committed Aug 21, 2024
1 parent 9b38de1 commit 6041de5
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 38 deletions.
7 changes: 3 additions & 4 deletions apps/react/src/store/anime/selectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { createSelector } from '@reduxjs/toolkit';

import { RootState } from '../store';

import { animeAdapter } from './state';

/** Select anime loading state. */
export const selectAnimeListLoading = createSelector(
(state: RootState) => state.anime.isLoading,
Expand All @@ -21,10 +23,7 @@ export const selectAnimeListError = createSelector(
);

/** Select all anime from store. */
export const selectAllAnime = createSelector(
(state: RootState) => state.anime.animeList.allIds.map(id => state.anime.animeList.byId[id]),
animeList => animeList,
);
export const selectAllAnime = animeAdapter.getSelectors<RootState>(state => state.anime).selectAll;

/** Select url to next page of anime list from store. */
export const selectNextPageUrl = createSelector(
Expand Down
27 changes: 7 additions & 20 deletions apps/react/src/store/anime/slice.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { createSlice } from '@reduxjs/toolkit';
import { createSlice, EntityState } from '@reduxjs/toolkit';
import { Anime } from '@js-camp/core/models/anime';

import { fetchList, fetchNewPage } from './dispatchers';
import { initialState } from './state';
import { animeAdapter, initialState } from './state';

/** Anime list slice. */
export const animeSlice = createSlice({
Expand All @@ -13,16 +14,9 @@ export const animeSlice = createSlice({
state.isLoading = true;
})
.addCase(fetchList.fulfilled, (state, action) => {
state.animeList.byId = {};
state.animeList.allIds = [];

action.payload.results.forEach(item => {
state.animeList.byId[item.id] = item;
state.animeList.allIds.push(item.id);
});

const animeState = state as EntityState<Anime>;
animeAdapter.setAll(animeState, action.payload.results);
state.nextPage = action.payload.next;
state.previousPage = action.payload.previous;
state.isLoading = false;
})
.addCase(fetchList.rejected, (state, action) => {
Expand All @@ -36,17 +30,10 @@ export const animeSlice = createSlice({
state.isAdditionalLoading = true;
})
.addCase(fetchNewPage.fulfilled, (state, action) => {
const { byId, allIds } = state.animeList;

action.payload.results.forEach(item => {
byId[item.id] = item;
if (!allIds.find(id => id === item.id)) {
allIds.push(item.id);
}
});
const animeState = state as EntityState<Anime>;
animeAdapter.addMany(animeState, action.payload.results);

state.nextPage = action.payload.next;
state.previousPage = action.payload.previous;
state.isAdditionalLoading = false;
})
.addCase(fetchNewPage.rejected, (state, action) => {
Expand Down
26 changes: 12 additions & 14 deletions apps/react/src/store/anime/state.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
import { Anime } from '@js-camp/core/models/anime';
import { createEntityAdapter } from '@reduxjs/toolkit';

import { NormalizedObjects } from '../store';
/** Anime adapter. */
export const animeAdapter = createEntityAdapter({
selectId: (anime: Anime) => anime.id,
});

/** Anime list state. */
export type AnimeListState = {

/** Anime list. */
readonly animeList: NormalizedObjects<Anime>;

/** Url to previous page of anime list. */
readonly previousPage: string | null;

/** Url to next page of anime list. */
readonly nextPage: string | null;

Expand All @@ -25,10 +23,10 @@ export type AnimeListState = {
};

/** Initial state for anime list state. */
export const initialState: AnimeListState = {
isLoading: false,
isAdditionalLoading: false,
animeList: { byId: {}, allIds: [] },
previousPage: null,
nextPage: null,
};
export const initialState = animeAdapter.getInitialState<AnimeListState>(
{
isLoading: false,
isAdditionalLoading: false,
nextPage: null,
},
);

0 comments on commit 6041de5

Please sign in to comment.