-
-
Notifications
You must be signed in to change notification settings - Fork 573
/
usePagination.js
78 lines (72 loc) · 2.49 KB
/
usePagination.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
import React, { useRef, useEffect } from 'react';
import { useHistory, useLocation } from 'react-router-dom';
import qs from 'query-string';
import { useSelector } from 'react-redux';
import { findBlocks, slugify } from '@plone/volto/helpers';
/**
* @function useCreatePageQueryStringKey
* @description A hook that creates a key with an id if there are multiple blocks with pagination.
* @returns {string} Example: page || page_012345678
*/
const useCreatePageQueryStringKey = (id) => {
const blockTypesWithPagination = ['search', 'listing'];
const blocks = useSelector((state) => state?.content?.data?.blocks) || [];
const hasMultiplePaginations =
findBlocks(blocks, blockTypesWithPagination).length > 1;
return hasMultiplePaginations ? slugify(`page-${id}`) : 'page';
};
const useGetBlockType = (id) => {
const blocks = useSelector((state) => state?.content?.data?.blocks) || [];
const block = blocks[id];
return block ? block?.['@type'] : null;
};
/**
* A pagination helper that tracks the query and resets pagination in case the
* query changes.
*/
export const usePagination = (id = null, defaultPage = 1) => {
const location = useLocation();
const history = useHistory();
const pageQueryStringKey = useCreatePageQueryStringKey(id);
const block_type = useGetBlockType(id);
const pageQueryParam =
qs.parse(location.search)[pageQueryStringKey] || defaultPage;
const [currentPage, setCurrentPageState] = React.useState(
parseInt(pageQueryParam),
);
const setCurrentPage = (page) => {
setCurrentPageState(page);
const newParams = {
...qs.parse(location.search),
[pageQueryStringKey]: page,
};
history.push({ search: qs.stringify(newParams) });
};
const queryRef = useRef(qs.parse(location.search)?.query);
useEffect(() => {
if (
queryRef.current !== qs.parse(location.search)?.query &&
block_type === 'search'
) {
setCurrentPageState(defaultPage);
const newParams = {
...qs.parse(location.search),
[pageQueryStringKey]: defaultPage,
};
delete newParams[pageQueryStringKey];
history.replace({ search: qs.stringify(newParams) });
queryRef.current = qs.parse(location.search)?.query;
} else {
setCurrentPageState(
parseInt(
qs.parse(location.search)?.[pageQueryStringKey] || defaultPage,
),
);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [location.search, block_type]);
return {
currentPage,
setCurrentPage,
};
};