Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import { IJsonapiModel, IJsonapiView, Response } from 'datx-jsonapi';
- import { useEffect, useMemo, useState } from 'react';
- interface IResponseWithNext<T extends IJsonapiModel> extends Response<T> {
- next: Promise<Response<T>>;
- }
- function responseHasNext(response: IResponseWithNext<IJsonapiModel>): true;
- function responseHasNext(response?: Response<IJsonapiModel>): false;
- function responseHasNext(response?: Response<IJsonapiModel> | IResponseWithNext<IJsonapiModel>): boolean {
- return Boolean(
- response &&
- response.pageInfo &&
- typeof response.pageInfo.currentPage === 'number' &&
- typeof response.pageInfo.totalPages === 'number' &&
- response.pageInfo.currentPage < response.pageInfo.totalPages &&
- 'next' in response,
- );
- }
- export const useInfiniteScroll = (view?: IJsonapiView) => {
- const [state, setState] = useState({
- latestResponse: view ? view.latestResponse : undefined,
- loading: false,
- view,
- });
- if (view && view !== state.view) {
- setState((oldState) => ({ ...oldState, view }));
- }
- if (view && view.latestResponse !== state.latestResponse) {
- setState((oldState) => ({ ...oldState, latestResponse: view.latestResponse }));
- }
- const loadMore = () => {
- if (state.view && responseHasNext(state.view.latestResponse) && !state.loading) {
- setState((oldState) => ({ ...oldState, loading: true }));
- (state.view.latestResponse as IResponseWithNext<IJsonapiModel>).next
- .then(() => {
- setState((oldState) => ({ ...oldState, loading: false }));
- }, () => {
- setState((oldState) => ({ ...oldState, loading: false }));
- });
- }
- };
- return useMemo(() => ({
- hasMore: state.latestResponse ? responseHasNext(state.latestResponse) : false,
- loadMore,
- loading: state.loading,
- }), [state]);
- };
Add Comment
Please, Sign In to add comment