Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
F
frontend
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
vicotor
frontend
Commits
bd4c82b1
Commit
bd4c82b1
authored
Jun 13, 2023
by
tom
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
disable pagination buttons when page is loading
parent
ae968845
Changes
8
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
49 additions
and
19 deletions
+49
-19
useIsInitialLoading.tsx
lib/hooks/useIsInitialLoading.tsx
+13
-0
AddressCsvExportLink.tsx
ui/address/AddressCsvExportLink.tsx
+3
-1
AddressTxsFilter.tsx
ui/address/AddressTxsFilter.tsx
+3
-1
TokenTransferFilter.tsx
ui/shared/TokenTransfer/TokenTransferFilter.tsx
+3
-1
Pagination.tsx
ui/shared/pagination/Pagination.tsx
+11
-8
types.ts
ui/shared/pagination/types.ts
+1
-0
useQueryWithPages.test.tsx
ui/shared/pagination/useQueryWithPages.test.tsx
+9
-0
useQueryWithPages.ts
ui/shared/pagination/useQueryWithPages.ts
+6
-8
No files found.
lib/hooks/useIsInitialLoading.tsx
0 → 100644
View file @
bd4c82b1
import
React
from
'
react
'
;
export
default
function
useIsInitialLoading
(
isLoading
:
boolean
|
undefined
)
{
const
[
isInitialLoading
,
setIsInitialLoading
]
=
React
.
useState
(
Boolean
(
isLoading
));
React
.
useEffect
(()
=>
{
if
(
!
isLoading
)
{
setIsInitialLoading
(
false
);
}
},
[
isLoading
]);
return
isInitialLoading
;
}
ui/address/AddressCsvExportLink.tsx
View file @
bd4c82b1
...
@@ -6,6 +6,7 @@ import type { CsvExportType } from 'types/client/address';
...
@@ -6,6 +6,7 @@ import type { CsvExportType } from 'types/client/address';
import
appConfig
from
'
configs/app/config
'
;
import
appConfig
from
'
configs/app/config
'
;
import
svgFileIcon
from
'
icons/files/csv.svg
'
;
import
svgFileIcon
from
'
icons/files/csv.svg
'
;
import
useIsInitialLoading
from
'
lib/hooks/useIsInitialLoading
'
;
import
useIsMobile
from
'
lib/hooks/useIsMobile
'
;
import
useIsMobile
from
'
lib/hooks/useIsMobile
'
;
import
LinkInternal
from
'
ui/shared/LinkInternal
'
;
import
LinkInternal
from
'
ui/shared/LinkInternal
'
;
...
@@ -18,12 +19,13 @@ interface Props {
...
@@ -18,12 +19,13 @@ interface Props {
const
AddressCsvExportLink
=
({
className
,
address
,
type
,
isLoading
}:
Props
)
=>
{
const
AddressCsvExportLink
=
({
className
,
address
,
type
,
isLoading
}:
Props
)
=>
{
const
isMobile
=
useIsMobile
();
const
isMobile
=
useIsMobile
();
const
isInitialLoading
=
useIsInitialLoading
(
isLoading
);
if
(
!
appConfig
.
reCaptcha
.
siteKey
)
{
if
(
!
appConfig
.
reCaptcha
.
siteKey
)
{
return
null
;
return
null
;
}
}
if
(
isLoading
)
{
if
(
is
Initial
Loading
)
{
return
(
return
(
<
Flex
className=
{
className
}
flexShrink=
{
0
}
alignItems=
"center"
>
<
Flex
className=
{
className
}
flexShrink=
{
0
}
alignItems=
"center"
>
<
Skeleton
boxSize=
{
{
base
:
'
32px
'
,
lg
:
6
}
}
borderRadius=
"base"
/>
<
Skeleton
boxSize=
{
{
base
:
'
32px
'
,
lg
:
6
}
}
borderRadius=
"base"
/>
...
...
ui/address/AddressTxsFilter.tsx
View file @
bd4c82b1
...
@@ -10,6 +10,7 @@ import React from 'react';
...
@@ -10,6 +10,7 @@ import React from 'react';
import
type
{
AddressFromToFilter
}
from
'
types/api/address
'
;
import
type
{
AddressFromToFilter
}
from
'
types/api/address
'
;
import
useIsInitialLoading
from
'
lib/hooks/useIsInitialLoading
'
;
import
FilterButton
from
'
ui/shared/filters/FilterButton
'
;
import
FilterButton
from
'
ui/shared/filters/FilterButton
'
;
interface
Props
{
interface
Props
{
...
@@ -21,13 +22,14 @@ interface Props {
...
@@ -21,13 +22,14 @@ interface Props {
const
AddressTxsFilter
=
({
onFilterChange
,
defaultFilter
,
isActive
,
isLoading
}:
Props
)
=>
{
const
AddressTxsFilter
=
({
onFilterChange
,
defaultFilter
,
isActive
,
isLoading
}:
Props
)
=>
{
const
{
isOpen
,
onToggle
}
=
useDisclosure
();
const
{
isOpen
,
onToggle
}
=
useDisclosure
();
const
isInitialLoading
=
useIsInitialLoading
(
isLoading
);
return
(
return
(
<
Menu
>
<
Menu
>
<
MenuButton
>
<
MenuButton
>
<
FilterButton
<
FilterButton
isActive=
{
isOpen
||
isActive
}
isActive=
{
isOpen
||
isActive
}
isLoading=
{
isLoading
}
isLoading=
{
is
Initial
Loading
}
onClick=
{
onToggle
}
onClick=
{
onToggle
}
as=
"div"
as=
"div"
/>
/>
...
...
ui/shared/TokenTransfer/TokenTransferFilter.tsx
View file @
bd4c82b1
...
@@ -9,6 +9,7 @@ import React from 'react';
...
@@ -9,6 +9,7 @@ import React from 'react';
import
type
{
AddressFromToFilter
}
from
'
types/api/address
'
;
import
type
{
AddressFromToFilter
}
from
'
types/api/address
'
;
import
type
{
TokenType
}
from
'
types/api/token
'
;
import
type
{
TokenType
}
from
'
types/api/token
'
;
import
useIsInitialLoading
from
'
lib/hooks/useIsInitialLoading
'
;
import
PopoverFilter
from
'
ui/shared/filters/PopoverFilter
'
;
import
PopoverFilter
from
'
ui/shared/filters/PopoverFilter
'
;
import
TokenTypeFilter
from
'
ui/shared/filters/TokenTypeFilter
'
;
import
TokenTypeFilter
from
'
ui/shared/filters/TokenTypeFilter
'
;
...
@@ -31,9 +32,10 @@ const TokenTransferFilter = ({
...
@@ -31,9 +32,10 @@ const TokenTransferFilter = ({
defaultAddressFilter
,
defaultAddressFilter
,
isLoading
,
isLoading
,
}:
Props
)
=>
{
}:
Props
)
=>
{
const
isInitialLoading
=
useIsInitialLoading
(
isLoading
);
return
(
return
(
<
PopoverFilter
appliedFiltersNum=
{
appliedFiltersNum
}
contentProps=
{
{
w
:
'
200px
'
}
}
isLoading=
{
isLoading
}
>
<
PopoverFilter
appliedFiltersNum=
{
appliedFiltersNum
}
contentProps=
{
{
w
:
'
200px
'
}
}
isLoading=
{
is
Initial
Loading
}
>
{
withAddressFilter
&&
(
{
withAddressFilter
&&
(
<>
<>
<
Text
variant=
"secondary"
fontWeight=
{
600
}
>
Address
</
Text
>
<
Text
variant=
"secondary"
fontWeight=
{
600
}
>
Address
</
Text
>
...
...
ui/shared/pagination/Pagination.tsx
View file @
bd4c82b1
...
@@ -9,29 +9,31 @@ interface Props extends PaginationParams {
...
@@ -9,29 +9,31 @@ interface Props extends PaginationParams {
className
?:
string
;
className
?:
string
;
}
}
const
Pagination
=
({
page
,
onNextPageClick
,
onPrevPageClick
,
resetPage
,
hasNextPage
,
className
,
canGoBackwards
,
isLoading
,
isVisible
}:
Props
)
=>
{
const
Pagination
=
({
page
,
onNextPageClick
,
onPrevPageClick
,
resetPage
,
has
Pages
,
has
NextPage
,
className
,
canGoBackwards
,
isLoading
,
isVisible
}:
Props
)
=>
{
if
(
!
isVisible
)
{
if
(
!
isVisible
)
{
return
null
;
return
null
;
}
}
const
showSkeleton
=
page
===
1
&&
!
hasPages
&&
isLoading
;
return
(
return
(
<
Flex
<
Flex
className=
{
className
}
className=
{
className
}
fontSize=
"sm"
fontSize=
"sm"
alignItems=
"center"
alignItems=
"center"
>
>
<
Skeleton
isLoaded=
{
!
isLoading
}
display=
"inline-block"
mr=
{
4
}
borderRadius=
"base"
>
<
Skeleton
isLoaded=
{
!
showSkeleton
}
display=
"inline-block"
mr=
{
4
}
borderRadius=
"base"
>
<
Button
<
Button
variant=
"outline"
variant=
"outline"
size=
"sm"
size=
"sm"
onClick=
{
resetPage
}
onClick=
{
resetPage
}
isDisabled=
{
page
===
1
}
isDisabled=
{
page
===
1
||
isLoading
}
>
>
First
First
</
Button
>
</
Button
>
</
Skeleton
>
</
Skeleton
>
<
Skeleton
isLoaded=
{
!
isLoading
}
display=
"inline-block"
mr=
{
3
}
borderRadius=
"base"
>
<
Skeleton
isLoaded=
{
!
showSkeleton
}
display=
"inline-block"
mr=
{
3
}
borderRadius=
"base"
>
<
IconButton
<
IconButton
variant=
"outline"
variant=
"outline"
onClick=
{
onPrevPageClick
}
onClick=
{
onPrevPageClick
}
...
@@ -39,10 +41,10 @@ const Pagination = ({ page, onNextPageClick, onPrevPageClick, resetPage, hasNext
...
@@ -39,10 +41,10 @@ const Pagination = ({ page, onNextPageClick, onPrevPageClick, resetPage, hasNext
aria
-
label=
"Prev page"
aria
-
label=
"Prev page"
w=
"36px"
w=
"36px"
icon=
{
<
Icon
as=
{
arrowIcon
}
w=
{
5
}
h=
{
5
}
/>
}
icon=
{
<
Icon
as=
{
arrowIcon
}
w=
{
5
}
h=
{
5
}
/>
}
isDisabled=
{
!
canGoBackwards
||
page
===
1
}
isDisabled=
{
!
canGoBackwards
||
page
===
1
||
isLoading
}
/>
/>
</
Skeleton
>
</
Skeleton
>
<
Skeleton
isLoaded=
{
!
isLoading
}
display=
"inline-block"
borderRadius=
"base"
>
<
Skeleton
isLoaded=
{
!
showSkeleton
}
display=
"inline-block"
borderRadius=
"base"
>
<
Button
<
Button
variant=
"outline"
variant=
"outline"
size=
"sm"
size=
"sm"
...
@@ -50,12 +52,13 @@ const Pagination = ({ page, onNextPageClick, onPrevPageClick, resetPage, hasNext
...
@@ -50,12 +52,13 @@ const Pagination = ({ page, onNextPageClick, onPrevPageClick, resetPage, hasNext
borderWidth=
"1px"
borderWidth=
"1px"
fontWeight=
{
400
}
fontWeight=
{
400
}
h=
{
8
}
h=
{
8
}
minW=
"36px"
cursor=
"unset"
cursor=
"unset"
>
>
{
page
}
{
page
}
</
Button
>
</
Button
>
</
Skeleton
>
</
Skeleton
>
<
Skeleton
isLoaded=
{
!
isLoading
}
display=
"inline-block"
ml=
{
3
}
borderRadius=
"base"
>
<
Skeleton
isLoaded=
{
!
showSkeleton
}
display=
"inline-block"
ml=
{
3
}
borderRadius=
"base"
>
<
IconButton
<
IconButton
variant=
"outline"
variant=
"outline"
onClick=
{
onNextPageClick
}
onClick=
{
onNextPageClick
}
...
@@ -63,7 +66,7 @@ const Pagination = ({ page, onNextPageClick, onPrevPageClick, resetPage, hasNext
...
@@ -63,7 +66,7 @@ const Pagination = ({ page, onNextPageClick, onPrevPageClick, resetPage, hasNext
aria
-
label=
"Next page"
aria
-
label=
"Next page"
w=
"36px"
w=
"36px"
icon=
{
<
Icon
as=
{
arrowIcon
}
w=
{
5
}
h=
{
5
}
transform=
"rotate(180deg)"
/>
}
icon=
{
<
Icon
as=
{
arrowIcon
}
w=
{
5
}
h=
{
5
}
transform=
"rotate(180deg)"
/>
}
isDisabled=
{
!
hasNextPage
}
isDisabled=
{
!
hasNextPage
||
isLoading
}
/>
/>
</
Skeleton
>
</
Skeleton
>
{
/* not implemented yet */
}
{
/* not implemented yet */
}
...
...
ui/shared/pagination/types.ts
View file @
bd4c82b1
...
@@ -3,6 +3,7 @@ export interface PaginationParams {
...
@@ -3,6 +3,7 @@ export interface PaginationParams {
onNextPageClick
:
()
=>
void
;
onNextPageClick
:
()
=>
void
;
onPrevPageClick
:
()
=>
void
;
onPrevPageClick
:
()
=>
void
;
resetPage
:
()
=>
void
;
resetPage
:
()
=>
void
;
hasPages
:
boolean
;
hasNextPage
:
boolean
;
hasNextPage
:
boolean
;
canGoBackwards
:
boolean
;
canGoBackwards
:
boolean
;
isLoading
:
boolean
;
isLoading
:
boolean
;
...
...
ui/shared/pagination/useQueryWithPages.test.tsx
View file @
bd4c82b1
...
@@ -68,6 +68,7 @@ it('returns correct data if there is only one page', async() => {
...
@@ -68,6 +68,7 @@ it('returns correct data if there is only one page', async() => {
hasNextPage
:
false
,
hasNextPage
:
false
,
isLoading
:
false
,
isLoading
:
false
,
isVisible
:
false
,
isVisible
:
false
,
hasPages
:
false
,
});
});
});
});
...
@@ -127,6 +128,7 @@ describe('if there are multiple pages', () => {
...
@@ -127,6 +128,7 @@ describe('if there are multiple pages', () => {
hasNextPage
:
true
,
hasNextPage
:
true
,
isLoading
:
false
,
isLoading
:
false
,
isVisible
:
true
,
isVisible
:
true
,
hasPages
:
true
,
});
});
expect
(
routerPush
).
toHaveBeenCalledTimes
(
1
);
expect
(
routerPush
).
toHaveBeenCalledTimes
(
1
);
...
@@ -164,6 +166,7 @@ describe('if there are multiple pages', () => {
...
@@ -164,6 +166,7 @@ describe('if there are multiple pages', () => {
hasNextPage
:
false
,
hasNextPage
:
false
,
isLoading
:
false
,
isLoading
:
false
,
isVisible
:
true
,
isVisible
:
true
,
hasPages
:
true
,
});
});
expect
(
routerPush
).
toHaveBeenCalledTimes
(
2
);
expect
(
routerPush
).
toHaveBeenCalledTimes
(
2
);
...
@@ -207,6 +210,7 @@ describe('if there are multiple pages', () => {
...
@@ -207,6 +210,7 @@ describe('if there are multiple pages', () => {
hasNextPage
:
true
,
hasNextPage
:
true
,
isLoading
:
false
,
isLoading
:
false
,
isVisible
:
true
,
isVisible
:
true
,
hasPages
:
true
,
});
});
expect
(
routerPush
).
toHaveBeenCalledTimes
(
3
);
expect
(
routerPush
).
toHaveBeenCalledTimes
(
3
);
...
@@ -254,6 +258,7 @@ describe('if there are multiple pages', () => {
...
@@ -254,6 +258,7 @@ describe('if there are multiple pages', () => {
hasNextPage
:
true
,
hasNextPage
:
true
,
isLoading
:
false
,
isLoading
:
false
,
isVisible
:
true
,
isVisible
:
true
,
hasPages
:
true
,
});
});
expect
(
routerPush
).
toHaveBeenCalledTimes
(
4
);
expect
(
routerPush
).
toHaveBeenCalledTimes
(
4
);
...
@@ -305,6 +310,7 @@ describe('if there are multiple pages', () => {
...
@@ -305,6 +310,7 @@ describe('if there are multiple pages', () => {
hasNextPage
:
true
,
hasNextPage
:
true
,
isLoading
:
false
,
isLoading
:
false
,
isVisible
:
true
,
isVisible
:
true
,
hasPages
:
true
,
});
});
expect
(
routerPush
).
toHaveBeenCalledTimes
(
3
);
expect
(
routerPush
).
toHaveBeenCalledTimes
(
3
);
...
@@ -368,6 +374,7 @@ describe('if there is page query param in URL', () => {
...
@@ -368,6 +374,7 @@ describe('if there is page query param in URL', () => {
hasNextPage
:
false
,
hasNextPage
:
false
,
isLoading
:
false
,
isLoading
:
false
,
isVisible
:
true
,
isVisible
:
true
,
hasPages
:
true
,
});
});
});
});
...
@@ -397,6 +404,7 @@ describe('if there is page query param in URL', () => {
...
@@ -397,6 +404,7 @@ describe('if there is page query param in URL', () => {
hasNextPage
:
false
,
hasNextPage
:
false
,
isLoading
:
false
,
isLoading
:
false
,
isVisible
:
true
,
isVisible
:
true
,
hasPages
:
true
,
});
});
expect
(
routerPush
).
toHaveBeenCalledTimes
(
1
);
expect
(
routerPush
).
toHaveBeenCalledTimes
(
1
);
...
@@ -447,6 +455,7 @@ describe('queries with filters', () => {
...
@@ -447,6 +455,7 @@ describe('queries with filters', () => {
hasNextPage
:
true
,
hasNextPage
:
true
,
isLoading
:
false
,
isLoading
:
false
,
isVisible
:
true
,
isVisible
:
true
,
hasPages
:
false
,
});
});
expect
(
routerPush
).
toHaveBeenCalledTimes
(
2
);
expect
(
routerPush
).
toHaveBeenCalledTimes
(
2
);
...
...
ui/shared/pagination/useQueryWithPages.ts
View file @
bd4c82b1
...
@@ -55,7 +55,7 @@ export default function useQueryWithPages<Resource extends PaginatedResources>({
...
@@ -55,7 +55,7 @@ export default function useQueryWithPages<Resource extends PaginatedResources>({
const
[
pageParams
,
setPageParams
]
=
React
.
useState
<
Record
<
number
,
NextPageParams
>>
({
const
[
pageParams
,
setPageParams
]
=
React
.
useState
<
Record
<
number
,
NextPageParams
>>
({
[
page
]:
getPaginationParamsFromQuery
(
router
.
query
.
next_page_params
),
[
page
]:
getPaginationParamsFromQuery
(
router
.
query
.
next_page_params
),
});
});
const
[
hasPag
ination
,
setHasPagination
]
=
React
.
useState
(
page
>
1
);
const
[
hasPag
es
,
setHasPages
]
=
React
.
useState
(
page
>
1
);
const
isMounted
=
React
.
useRef
(
false
);
const
isMounted
=
React
.
useRef
(
false
);
const
canGoBackwards
=
React
.
useRef
(
!
router
.
query
.
page
);
const
canGoBackwards
=
React
.
useRef
(
!
router
.
query
.
page
);
...
@@ -93,7 +93,7 @@ export default function useQueryWithPages<Resource extends PaginatedResources>({
...
@@ -93,7 +93,7 @@ export default function useQueryWithPages<Resource extends PaginatedResources>({
next_page_params
:
encodeURIComponent
(
JSON
.
stringify
(
data
.
next_page_params
)),
next_page_params
:
encodeURIComponent
(
JSON
.
stringify
(
data
.
next_page_params
)),
};
};
setHasPag
ination
(
true
);
setHasPag
es
(
true
);
scrollToTop
();
scrollToTop
();
router
.
push
({
pathname
:
router
.
pathname
,
query
:
nextPageQuery
},
undefined
,
{
shallow
:
true
});
router
.
push
({
pathname
:
router
.
pathname
,
query
:
nextPageQuery
},
undefined
,
{
shallow
:
true
});
},
[
data
?.
next_page_params
,
page
,
router
,
scrollToTop
]);
},
[
data
?.
next_page_params
,
page
,
router
,
scrollToTop
]);
...
@@ -116,7 +116,6 @@ export default function useQueryWithPages<Resource extends PaginatedResources>({
...
@@ -116,7 +116,6 @@ export default function useQueryWithPages<Resource extends PaginatedResources>({
setPage
(
prev
=>
prev
-
1
);
setPage
(
prev
=>
prev
-
1
);
page
===
2
&&
queryClient
.
removeQueries
({
queryKey
:
[
resourceName
]
});
page
===
2
&&
queryClient
.
removeQueries
({
queryKey
:
[
resourceName
]
});
});
});
setHasPagination
(
true
);
},
[
router
,
page
,
pageParams
,
scrollToTop
,
queryClient
,
resourceName
]);
},
[
router
,
page
,
pageParams
,
scrollToTop
,
queryClient
,
resourceName
]);
const
resetPage
=
useCallback
(()
=>
{
const
resetPage
=
useCallback
(()
=>
{
...
@@ -135,8 +134,6 @@ export default function useQueryWithPages<Resource extends PaginatedResources>({
...
@@ -135,8 +134,6 @@ export default function useQueryWithPages<Resource extends PaginatedResources>({
queryClient
.
removeQueries
({
queryKey
:
[
resourceName
],
type
:
'
inactive
'
});
queryClient
.
removeQueries
({
queryKey
:
[
resourceName
],
type
:
'
inactive
'
});
},
100
);
},
100
);
});
});
setHasPagination
(
true
);
},
[
queryClient
,
resourceName
,
router
,
scrollToTop
]);
},
[
queryClient
,
resourceName
,
router
,
scrollToTop
]);
const
onFilterChange
=
useCallback
((
newFilters
:
PaginationFilters
<
Resource
>
|
undefined
)
=>
{
const
onFilterChange
=
useCallback
((
newFilters
:
PaginationFilters
<
Resource
>
|
undefined
)
=>
{
...
@@ -148,7 +145,6 @@ export default function useQueryWithPages<Resource extends PaginatedResources>({
...
@@ -148,7 +145,6 @@ export default function useQueryWithPages<Resource extends PaginatedResources>({
}
}
});
});
}
}
setHasPagination
(
false
);
scrollToTop
();
scrollToTop
();
router
.
push
(
router
.
push
(
{
{
...
@@ -158,6 +154,7 @@ export default function useQueryWithPages<Resource extends PaginatedResources>({
...
@@ -158,6 +154,7 @@ export default function useQueryWithPages<Resource extends PaginatedResources>({
undefined
,
undefined
,
{
shallow
:
true
},
{
shallow
:
true
},
).
then
(()
=>
{
).
then
(()
=>
{
setHasPages
(
false
);
setPage
(
1
);
setPage
(
1
);
setPageParams
({});
setPageParams
({});
});
});
...
@@ -171,10 +168,11 @@ export default function useQueryWithPages<Resource extends PaginatedResources>({
...
@@ -171,10 +168,11 @@ export default function useQueryWithPages<Resource extends PaginatedResources>({
onNextPageClick
,
onNextPageClick
,
onPrevPageClick
,
onPrevPageClick
,
resetPage
,
resetPage
,
hasPages
,
hasNextPage
,
hasNextPage
,
canGoBackwards
:
canGoBackwards
.
current
,
canGoBackwards
:
canGoBackwards
.
current
,
isLoading
:
queryResult
.
isPlaceholderData
&&
!
hasPagination
,
isLoading
:
queryResult
.
isPlaceholderData
,
isVisible
:
hasPag
ination
||
(
!
queryResult
.
isLoading
&&
!
queryResult
.
isError
&&
hasNextPage
)
,
isVisible
:
hasPag
es
||
hasNextPage
,
};
};
React
.
useEffect
(()
=>
{
React
.
useEffect
(()
=>
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment