I have got an API which displays categories of music on the browser and I am trying to create a custom hook for pagination, but I keep getting this error, object is not iterable.
I am new to custom hooks and could really use some help. Can anyone shed some light on how to fix this?
Custom hook
JavaScript
x
68
68
1
`import React, {useState} from 'react';
2
import getToken from '../api/getToken';
3
4
const usePagination = (initialState) => {
5
const {categoriesPerPage, data, startFrom} = initialState;
6
const perPage = categoriesPerPage ? categoriesPerPage : 5;
7
const pages = Math.ceil(data.length / perPage);
8
const pagination = [];
9
const [currentPage, setCurrentPage] = useState(startFrom <= pages ? startFrom : 1);
10
const [slicedData, setSlicedData] = useState([...data].slice((currentPage -1) * perPage, currentPage * perPage));
11
12
let ellipsisLeft = false;
13
let ellipsisRight = false;
14
for(let i = 1; i <= pages; i++) {
15
if(i === currentPage) {
16
pagination.push(
17
{id: i, current: true, ellipsis: false}
18
);
19
} else {
20
if(i > pages - 1 || i === currentPage -1 || i === currentPage + 1){
21
pagination.push(
22
{id: i, current: false, ellipsis: false}
23
);
24
} else if(i > 1 && i < currentPage && !ellipsisLeft) {
25
pagination.push(
26
{id: i, current: false, ellipsis: true}
27
);
28
ellipsisLeft = true;
29
}else if (i < pages && i > currentPage && !ellipsisRight) {
30
pagination.push(
31
{id: i, current: false, ellipsis: true}
32
);
33
ellipsisRight = true;
34
}
35
}
36
}
37
const changePage = (page, e) => {
38
e.preventDefault();
39
if(page !== currentPage) {
40
setCurrentPage(page);
41
setSlicedData([...data].slice((page - 1) * perPage, page * perPage))
42
}
43
}
44
const goToPrevPage = (e) => {
45
e.preventDefault();
46
setCurrentPage(prevVal => prevVal - 1 === 0 ? prevVal : prevVal - 1);
47
if (currentPage !== 1) {
48
setSlicedData([...data].slice((currentPage - 2) * perPage, (currentPage - 1) * perPage));
49
}
50
}
51
const goToNextPage = (e) => {
52
e.preventDefault();
53
setCurrentPage(prevVal => prevVal === pages ? prevVal : prevVal + 1);
54
if (currentPage !== pages) {
55
setSlicedData([...data].slice(currentPage * perPage, (currentPage + 1) * perPage));
56
}
57
}
58
return {
59
slicedData,
60
pagination,
61
prevPage: goToPrevPage,
62
nextPage: goToNextPage,
63
changePage
64
}
65
}
66
67
export default usePagination;`
68
Pagination component
JavaScript
1
38
38
1
`import React, {Fragment} from 'react'
2
3
import usePagination from '../customHook/usePagination'
4
5
const Pagination = (props) => {
6
const {categoriesPerPage, data, startFrom } = props;
7
const [slicedData, pagination, prevPage, nextPage, changePage] = usePagination({categoriesPerPage, data, startFrom});
8
return (
9
<Fragment>
10
<nav className='pagination'>
11
<a href='/#' onClick={props.prev} className='pagination-prev'>Prev</a>
12
<a href='/#' onClick={props.next} className='pagination-next'>Next</a>
13
<ul className='pagination-list'>
14
{pagination.map(page => {
15
if(!page.ellipsis) {
16
return <li key={page.id}>
17
<a
18
href='#'
19
onClick={(e) => changePage(page.id, e)}
20
>
21
{page.id}
22
</a>
23
</li>
24
25
}else {
26
return <li key={page.id}>
27
<span className='pagination-ellipsis'>…</span>
28
</li>
29
}
30
})}
31
</ul>
32
</nav>
33
</Fragment>
34
)
35
}
36
37
export default Pagination`
38
app.js
JavaScript
1
48
48
1
`import Header from './Header';
2
3
import { useEffect, useState } from 'react';
4
import getInitalCategories from '../api/getInitalCategories';
5
import Pagination from './Pagination';
6
7
function App() {
8
const [categories, setCategories] = useState([]);
9
10
useEffect(() => {
11
getInitalCategories()
12
.then(data => setCategories(data.items))
13
.catch(e => console.log('oh no!', e));
14
}, []);
15
console.log(categories)
16
return (
17
<div className="App">
18
<Header />
19
<section
20
style={{
21
display: 'flex',
22
flexWrap: 'wrap',
23
alignContent: 'space-between',
24
justifyContent: 'space-between',
25
}}
26
>
27
{categories.map(cat => (
28
<div onClick={() => {}} style={{ cursor: 'pointer' }}>
29
<h2 style={{ textAlign: 'center', fontWeight: 200 }}>{cat.name}</h2>
30
<img
31
src={cat.icons[0].url}
32
alt={cat.name}
33
style={{
34
height: cat.icons[0].height,
35
width: cat.icons[0].width,
36
borderRadius: '10%',
37
}}
38
/>
39
</div>
40
))}
41
</section>
42
<Pagination data={categories} categoriesPerPage={5} startFrom={5}/>
43
</div>
44
);
45
}
46
47
export default App;`
48
Advertisement
Answer
The error is because categoriesPerPage, data, startFrom
these three are not defined in your pagination component. However you have passed these properties as prop to Pagination Component but you aren’t accessing them
just destructing those properties from props will work. Add below line before calling usePagination()
in your Pagination component. Thank you
JavaScript
1
2
1
const {categroiesPerPage, data, startFrom } = props;
2