Reputation: 95
I'm getting data from Django Rest API and React for Frontend, and I need to create the pagination with posts. I did it all in pagination component. I created the state with current page and I'm changing it by clicking on the page button in component like this:
const Paginator = () => {
const [count, setCount] = useState(null);
const [currentPage, setCurrentPage] = useState(1);
const [totalPages, setTotalPages] = useState(null);
const [nextPage, setNextPage] = useState(null);
const [previousPage, setPreviousPage] = useState(null);
const [valid, setValid] = useState(false);
useEffect(() => {
fetch(`http://127.0.0.1:8000/api/software/?p=${currentPage}`)
.then(response => response.json())
.then(data => {
setCount(data.count);
setTotalPages(data.total_pages)
setNextPage(data.links.next);
setPreviousPage(data.links.previous);
setValid(true);
})
}, [currentPage]);
...
return (
<>
{
...
<PbStart style={style} totalPages={range(1, totalPages+1)} setCurrentPage={setCurrentPage} />
...
}
</>
);
};
const PagItem = ({key, handleClick, className, title, name }) => {
return (
<li key={key} onClick={handleClick}>
<Link to='/' className={className} title={`Go to page ${title}`}>
{name}
</Link>
</li>
);
};
const PbStart = ({ style, totalPages, setCurrentPage }) => {
return (
...
{totalPages.map(p => (
<PagItem key={p} handleClick={() => setCurrentPage(p)} title={p} name={p} />
))}
...
);
};
And in posts component I don't know how to change current page, or getting it from the paginaton component. I've written that like this:
const Softwares = () => {
const [softwares, setSoftwares] = useState([]);
const [currentPage, setCurrentPage] = useState(1);
const [valid, setValid] = useState(false);
useEffect(() => {
fetch(`http://127.0.0.1:8000/api/software/?p=${currentPage}`)
.then(response => response.json())
.then(data => {
setSoftwares(data.results);
setValid(true);
})
}, [currentPage]);
return (
<>
{
...
{softwares.map(s => (
<Article key={s.id} pathname={s.id} title={s.title} image={s.image} pubdate={s.pub_date} icon={s.category.parent.img} categoryID={s.category.id} categoryName={s.category.name} dCount={s.counter} content={s.content} />
))}
...
}
</>
);
};
So, how to do that(get the current page from pagination component or another way)?
Upvotes: 0
Views: 303
Reputation: 574
I think a Paginator's job is only moving between pages and updating current page state. It should not be fetching data by itself, you can provide functionality to do extra work with props.
I haven't tested this, but this might be a good starting point.
With the example below you'll have a list of articles and then below it next and previous buttons.
In Softwares
, as you can see I am passing the same function for handling next and previous pages, you can refactor it to have one function like onPageMove
and call this function handleNext
and handlePrev
.
I added two separate functions if you have want to handle something different in either.
const Paginator = ({
total, // Required: Total records
startPage = 1, // Start from page / initialize current page to
limit = 30, // items per page
onMoveNext = null, // function to call next page,
onMovePrev = null, // function to call previous page
}) => {
const [currentPage, setCurrentPage] = useState(startPage);
const canGoNext = total >= limit;
const canGoPrev = currentPage > 1;
function handleNext(e) {
if (canGoNext) {
setCurrentPage((prevState) => prevState+1);
onMoveNext && onMoveNext({ currentPage });
}
}
function handlePrev(e) {
if (canGoPrev) {
setCurrentPage((prevState) => prevState-1);
onMovePrev && onMovePrev({ currentPage });
}
}
return (
<div>
<button onClick={handlePrev} disabled={!canGoPrev}>Prev</button>
<button onClick={handleNext} disabled={!canGoNext}>Next</button>
</div>
);
};
Here is how you can use Paginator in other components.
const PER_PAGE = 30; // get max # of records per page
const Softwares = () => {
const [softwares, setSoftwares] = useState([]);
const [valid, setValid] = useState(false);
const onFetchData = ({ currentPage }) => {
fetch(`http://127.0.0.1:8000/api/software/?p=${currentPage}&per_page=${PER_PAGE}`)
.then(response => response.json())
.then(data => {
setSoftwares(data.results);
setValid(true);
})
}
useEffect(() => {
onFetchData({ currentPage: 1 })
}, []);
return (
<>
{softwares.map(s => (
<Article key={s.id} pathname={s.id} title={s.title} image={s.image} pubdate={s.pub_date} icon={s.category.parent.img} categoryID={s.category.id} categoryName={s.category.name} dCount={s.counter} content={s.content} />
))}
<Paginator total={softwares.length} limit={PER_PAGE} onMoveNext={onFetchData} onMovePrev={onFetchData} />
</>
);
};
Upvotes: 1