Google Books API передает не все книги
пишу приложение по поиску книг с использованием Google Books API. Столкнулся с проблемой, что сервер в конечном итоге отправляет не все книги при дополнительной загрузке по принципу "load more". То есть, в итоговом массиве в приложении книг меньше чем сервер сообщает в момент первого запроса в поле totalItems. И не могу понять это в моем коде ошибка или это такое странное поведение Google Books API. Может кто сталкивался с аналогичной проблемой?
apiConfig с логикой запроса:
import axios from 'axios';
export const BASE_URL = 'https://www.googleapis.com/books/v1/volumes';
export const API_KEY = 'AIzaSyClgTthPOW8evajugq_vxS3U_Gf3V-IvT1';
export const MAX_RESULTS = 30;
export const loadData = async ({
search = '',
category = '',
sort = 'relevance',
page = 0,
}) => {
const selectedCategory = category === 'all' ? '' : category;
const startIndex = page * MAX_RESULTS;
try {
const response = await axios.get(
`${BASE_URL}?q=${search}+subject:${selectedCategory}&orderBy=${sort}&startIndex=${startIndex}&maxResults=${MAX_RESULTS}&key=${API_KEY}`
);
return response.data;
} catch (error) {
throw new Error(error.message);
}
};
Redux срез:
import { createAsyncThunk, createSlice } from '@reduxjs/toolkit';
import { MAX_RESULTS } from '../../apiConfig';
export const loadBooks = createAsyncThunk(
'@@books/loadBooks',
async ({ search, category, sort }, { extra: api }) => {
const response = await api.loadData({ search, category, sort });
return response;
}
);
export const loadMoreBooks = createAsyncThunk(
'@@books/loadMoreBooks',
async ({ search, category, sort, page }, { extra: api }) => {
const response = await api.loadData({ search, category, sort, page });
return response;
}
);
const initialState = {
loading: 'idle', // pending / succeeded / failed
loadingButton: false,
entities: [],
total: null,
page: 0,
error: null,
};
export const booksSlice = createSlice({
name: '@@books',
initialState,
reducers: {
setError: (state, action) => {
state.error = action.payload;
},
clearBooks: () => initialState,
},
extraReducers: (builder) => {
builder
.addCase(loadBooks.pending, (state) => {
state.loading = 'pending';
state.entities = [];
state.total = null;
state.page = 0;
state.error = null;
})
.addCase(loadBooks.fulfilled, (state, action) => {
state.loading = 'succeeded';
state.entities = action.payload.items;
state.total = action.payload.totalItems;
state.page = state.page + 1;
state.error = null;
})
.addCase(loadBooks.rejected, (state, action) => {
state.loading = 'failed';
state.error = action.error.message;
})
.addCase(loadMoreBooks.pending, (state) => {
state.loadingButton = true;
})
.addCase(loadMoreBooks.fulfilled, (state, action) => {
state.entities = state.entities.concat(action.payload.items || []);
state.page = state.page + 1;
state.loadingButton = false;
})
.addCase(loadMoreBooks.rejected, (state, action) => {
state.error = action.error.message;
state.loadingButton = false;
});
},
});
export const { setError, clearBooks } = booksSlice.actions;
export const booksReducer = booksSlice.reducer;
// selectors
export const selectBooksAllInfo = (state) => state.books;
export const selectBooks = (state) => state.books.entities;
export const selectError = (state) => state.books.error;
Баттон Load More:
<LoadingButton
variant="contained"
loading={loadingButton}
onClick={() =>
dispatch(loadMoreBooks({ search, category, sort, page }))
}
>
More books
</LoadingButton>
Хочу сделать чтобы эта кнопка не рендерилась если например число оставшихся книг на сервере меньше или равно нулю:
const remainingBooksForLoad = total - entities?.length;