I am using react-paginate (https://www.npmjs.com/package/react-paginate) to make pagination for my app. Everything is fine but I cannot increase the current number of the page. So for this here is my parent component:
import React, { useEffect, useState } from "react";
import Product from "../components/sub-components/Product";
import SimpleBox from "../components/sub-components/SimpleBox";
import BoxWithSearch from "../components/sub-components/BoxWithSearch";
import LoadingBox from "../components/sub-components/LoadingBox";
import MessageBox from "../components/sub-components/MessageBox";
import Cart from "../components/sub-components/Cart";
import { useDispatch, useSelector } from "react-redux";
import { listProducts } from "../actions/productActions";
import ReactPaginate from "react-paginate";
export default function HomeScreen() {
const dispatch = useDispatch();
const productList = useSelector((state) => state.productList);
const { loading, error, products } = productList;
const [currentPage, setCurrentPage] = useState(1);
const [pageCount, setpageCount] = useState(0);
useEffect(() => {
dispatch(listProducts(currentPage));
console.log(currentPage);
}, [dispatch]);
const handlePageClick = (data) => {
setCurrentPage(data.selected + 1);
// scroll to the top
//window.scrollTo(0, 0)
};
return (
<div className="container">
<div className="row">
<div className="col-lg-6 col-md-12 col-sm-12 col-xs-12">
<h2 className="title">Products</h2>
<div className="product-type-filter">
<button>Mug</button>
<button className="clicked">Shirt</button>
</div>
<div className="products">
<div className="row">
<div>
{loading ? (
<LoadingBox></LoadingBox>
) : error ? (
<MessageBox variant="danger">{error}</MessageBox>
) : (
<div className="row center">
{products.map((product) => (
<Product key={product.added} product={product}></Product>
))}
</div>
)}
</div>
</div>
</div>
<ReactPaginate
previousLabel={"Prev"}
nextLabel={"Next"}
pageCount={40}
marginPagesDisplayed={4}
pageRangeDisplayed={1}
onPageChange={handlePageClick}
containerClassName={"pagination justify-content-center"}
pageClassName={"page-item"}
pageLinkClassName={"page-link"}
previousClassName={"page-item"}
previousLinkClassName={"page-link"}
nextClassName={"page-item"}
nextLinkClassName={"page-link"}
breakClassName={"page-item"}
breakLinkClassName={"page-link"}
activeClassName={"active"}
/>
</div>
</div>
</div>
);
}
And my action for fetching the data:
import Axios from 'axios';
import {
PRODUCT_LIST_FAIL,
PRODUCT_LIST_REQUEST,
PRODUCT_LIST_SUCCESS,
} from '../constants/productConstants';
export const listProducts = () => async (dispatch, currentPage) => {
dispatch({
type: PRODUCT_LIST_REQUEST,
});
try {
const { data } = await Axios.get(`http://localhost:3000/items?_page=${currentPage}&_limit=16`);
dispatch({ type: PRODUCT_LIST_SUCCESS, payload: data });
} catch (error) {
dispatch({ type: PRODUCT_LIST_FAIL, payload: error.message });
}
};
But the problem is since the currentPage doesn't change, I cannot go to the other page. Do you have a solution for this? Thanks...
If you are updating the current page and wanting to fetch new data then you might want to add currentPage
to the useEffect
dependency array so the next current page of products is fetched/listed.
useEffect(() => {
dispatch(listProducts(currentPage));
console.log(currentPage);
}, [currentPage, dispatch]);
When I write
console.log(currentPage)
in action, I am getting this:ƒ getState() { var state = unliftState(liftedStore.getState()); if (state !== undefined) { lastDefinedState = state; } return lastDefinedState; }
How can I pass thecurrentpage
number into action?
In thunks, the second argument is the getState
function to be called and get the current redux state. Your listProducts
action creator is naming the getState
callback currentPage
. Also, any arguments being passed to listProducts
are being ignored (note the empty arg list in the outer function).
export const listProducts = () => async (dispatch, currentPage) => {
dispatch({
type: PRODUCT_LIST_REQUEST,
});
try {
const { data } = await Axios.get(`http://localhost:3000/items?_page=${currentPage}&_limit=16`);
dispatch({ type: PRODUCT_LIST_SUCCESS, payload: data });
} catch (error) {
dispatch({ type: PRODUCT_LIST_FAIL, payload: error.message });
}
};
listProducts
needs to consume the passed currentPage
argument in the outer functions, and enclose it in function scope.
export const listProducts = (currentPage) => async (dispatch) => {
dispatch({
type: PRODUCT_LIST_REQUEST,
});
try {
const { data } = await Axios.get(`http://localhost:3000/items?_page=${currentPage}&_limit=16`);
dispatch({ type: PRODUCT_LIST_SUCCESS, payload: data });
} catch (error) {
dispatch({ type: PRODUCT_LIST_FAIL, payload: error.message });
}
};