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
`import React, {useState} from 'react'; import getToken from '../api/getToken'; const usePagination = (initialState) => { const {categoriesPerPage, data, startFrom} = initialState; const perPage = categoriesPerPage ? categoriesPerPage : 5; const pages = Math.ceil(data.length / perPage); const pagination = []; const [currentPage, setCurrentPage] = useState(startFrom <= pages ? startFrom : 1); const [slicedData, setSlicedData] = useState([...data].slice((currentPage -1) * perPage, currentPage * perPage)); let ellipsisLeft = false; let ellipsisRight = false; for(let i = 1; i <= pages; i++) { if(i === currentPage) { pagination.push( {id: i, current: true, ellipsis: false} ); } else { if(i > pages - 1 || i === currentPage -1 || i === currentPage + 1){ pagination.push( {id: i, current: false, ellipsis: false} ); } else if(i > 1 && i < currentPage && !ellipsisLeft) { pagination.push( {id: i, current: false, ellipsis: true} ); ellipsisLeft = true; }else if (i < pages && i > currentPage && !ellipsisRight) { pagination.push( {id: i, current: false, ellipsis: true} ); ellipsisRight = true; } } } const changePage = (page, e) => { e.preventDefault(); if(page !== currentPage) { setCurrentPage(page); setSlicedData([...data].slice((page - 1) * perPage, page * perPage)) } } const goToPrevPage = (e) => { e.preventDefault(); setCurrentPage(prevVal => prevVal - 1 === 0 ? prevVal : prevVal - 1); if (currentPage !== 1) { setSlicedData([...data].slice((currentPage - 2) * perPage, (currentPage - 1) * perPage)); } } const goToNextPage = (e) => { e.preventDefault(); setCurrentPage(prevVal => prevVal === pages ? prevVal : prevVal + 1); if (currentPage !== pages) { setSlicedData([...data].slice(currentPage * perPage, (currentPage + 1) * perPage)); } } return { slicedData, pagination, prevPage: goToPrevPage, nextPage: goToNextPage, changePage } } export default usePagination;`
Pagination component
`import React, {Fragment} from 'react' import usePagination from '../customHook/usePagination' const Pagination = (props) => { const {categoriesPerPage, data, startFrom } = props; const [slicedData, pagination, prevPage, nextPage, changePage] = usePagination({categoriesPerPage, data, startFrom}); return ( <Fragment> <nav className='pagination'> <a href='/#' onClick={props.prev} className='pagination-prev'>Prev</a> <a href='/#' onClick={props.next} className='pagination-next'>Next</a> <ul className='pagination-list'> {pagination.map(page => { if(!page.ellipsis) { return <li key={page.id}> <a href='#' onClick={(e) => changePage(page.id, e)} > {page.id} </a> </li> }else { return <li key={page.id}> <span className='pagination-ellipsis'>…</span> </li> } })} </ul> </nav> </Fragment> ) } export default Pagination`
app.js
`import Header from './Header'; import { useEffect, useState } from 'react'; import getInitalCategories from '../api/getInitalCategories'; import Pagination from './Pagination'; function App() { const [categories, setCategories] = useState([]); useEffect(() => { getInitalCategories() .then(data => setCategories(data.items)) .catch(e => console.log('oh no!', e)); }, []); console.log(categories) return ( <div className="App"> <Header /> <section style={{ display: 'flex', flexWrap: 'wrap', alignContent: 'space-between', justifyContent: 'space-between', }} > {categories.map(cat => ( <div onClick={() => {}} style={{ cursor: 'pointer' }}> <h2 style={{ textAlign: 'center', fontWeight: 200 }}>{cat.name}</h2> <img src={cat.icons[0].url} alt={cat.name} style={{ height: cat.icons[0].height, width: cat.icons[0].width, borderRadius: '10%', }} /> </div> ))} </section> <Pagination data={categories} categoriesPerPage={5} startFrom={5}/> </div> ); } export default App;`
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
const {categroiesPerPage, data, startFrom } = props;