I am trying to call a method so I can paginate data from an API by passing the currentPage as a parameter, but I don't know what am I getting wrong. I have managed to pass the props like client_id but I couldn't deal with currentPage
The method onPageChanged should set the state of currentPage and then launch the request so I can fetch the posts of the currentPage
The instance looks like this:
instance.fetchConfig = (params) => {
return instance.get(
"/reiews?client_id=" params.client_id "&?page=" params.currentPage,
{
headers: {
Authorization: "Bearer " params.token,
},
}
);
};
Here is my App component :
class App extends Component {
constructor(props) {
super(props);
this.conteneur = React.createRef();
this.state = {
posts: [],
allPosts: null,
currentPage: null,
loading: false,
widgetStatus: true,
params: {
client_id: null,
localstore_id: null,
token: null,
currentPage: null,
},
};
}
onPageChanged = (data) => {
const currentPage = data.selected;
this.setState(
{
currentPage: currentPage,
},
() => {
this.receivedData();
}
);
console.log(data);
};
receivedData = () => {
let newData = { ...this.state };
newData.params = {
client_id: this.props.client,
localstore_id: this.props.shop,
token: this.props.token,
currentPage: this.state.currentPage,
};
Api.fetchWidgetConfig(newData.params)
.catch((error) => {
if (typeof error.message !== "undefined") {
newData.widgetStatus = false;
this.setState(newData);
}
return { data: { data: [] } };
})
.then((response) => {
if (response.data.status === "success") {
return response.data.data;
}
this.setState({
posts: [...response.data.posts.items],
allPosts: response.data.posts.total,
loading: false,
});
});
};
componentDidMount() {
this.setState({ loading: true });
this.receivedData();
}
}
export default App;
And this is the pagination component :
const LEFT_PAGE = "LEFT";
const RIGHT_PAGE = "RIGHT";
const range = (from, to, step = 1) => {
let i = from;
const range = [];
while (i <= to) {
range.push(i);
i = step;
}
return range;
};
class Paginate extends Component {
constructor(props) {
super(props);
const { totalRecords = null, pageLimit = 5, pageNeighbours = 0 } = props;
this.pageLimit = typeof pageLimit === "number" ? pageLimit : 5;
this.totalRecords = typeof totalRecords === "number" ? totalRecords : 0;
this.pageNeighbours =
typeof pageNeighbours === "number"
? Math.max(0, Math.min(pageNeighbours, 2))
: 0;
this.totalPages = Math.ceil(this.totalRecords / this.pageLimit);
this.state = { currentPage: 1 };
}
componentDidMount() {
this.gotoPage(1);
}
gotoPage = (page) => {
const { onPageChanged = (f) => f } = this.props;
const currentPage = Math.max(0, Math.min(page, this.totalPages));
const paginationData = {
currentPage,
totalPages: this.totalPages,
pageLimit: this.pageLimit,
totalRecords: this.totalRecords,
};
this.setState({ currentPage }, () => onPageChanged(paginationData));
};
handleClick = (page, evt) => {
evt.preventDefault();
this.gotoPage(page);
};
handleMoveLeft = (evt) => {
evt.preventDefault();
this.gotoPage(this.state.currentPage - this.pageNeighbours * 2 - 1);
};
handleMoveRight = (evt) => {
evt.preventDefault();
this.gotoPage(this.state.currentPage this.pageNeighbours * 2 1);
};
fetchPageNumbers = () => {
const totalPages = this.totalPages;
const currentPage = this.state.currentPage;
const pageNeighbours = this.pageNeighbours;
const totalNumbers = this.pageNeighbours * 2 3;
const totalBlocks = totalNumbers 2;
if (totalPages > totalBlocks) {
let pages = [];
const leftBound = currentPage - pageNeighbours;
const rightBound = currentPage pageNeighbours;
const beforeLastPage = totalPages - 1;
const startPage = leftBound > 2 ? leftBound : 2;
const endPage = rightBound < beforeLastPage ? rightBound : beforeLastPage;
pages = range(startPage, endPage);
const pagesCount = pages.length;
const singleSpillOffset = totalNumbers - pagesCount - 1;
const leftSpill = startPage > 2;
const rightSpill = endPage < beforeLastPage;
const leftSpillPage = LEFT_PAGE;
const rightSpillPage = RIGHT_PAGE;
if (leftSpill && !rightSpill) {
const extraPages = range(startPage - singleSpillOffset, startPage - 1);
pages = [leftSpillPage, ...extraPages, ...pages];
} else if (!leftSpill && rightSpill) {
const extraPages = range(endPage 1, endPage singleSpillOffset);
pages = [...pages, ...extraPages, rightSpillPage];
} else if (leftSpill && rightSpill) {
pages = [leftSpillPage, ...pages, rightSpillPage];
}
return [1, ...pages, totalPages];
}
return range(1, totalPages);
};
render() {
if (!this.totalRecords) return null;
if (this.totalPages === 1) return null;
const { currentPage } = this.state;
const pages = this.fetchPageNumbers();
return (
<Fragment>
<PaginateWrapper>
{pages.map((page, index) => {
if (page === LEFT_PAGE)
return (
<PaginateBtn
key={index}
aria-label="Previous"
onClick={this.handleMoveLeft}
>
<IconPrev
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
d="M15 19l-7-7 7-7"
/>
</IconPrev>
Précédent
</PaginateBtn>
);
if (page === RIGHT_PAGE)
return (
<PaginateBtn
key={index}
aria-label="Next"
onClick={this.handleMoveRight}
>
Suivant
<IconNext
xmlns="http://www.w3.org/2000/svg"
className="h-4 w-4 inline-block ml-2"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
d="M9 5l7 7-7 7"
/>
</IconNext>
</PaginateBtn>
);
return (
<PaginateBtn
key={index}
onClick={(e) => this.handleClick(page, e)}
activePage={currentPage === page}
>
{page}
</PaginateBtn>
);
})}
</PaginateWrapper>
</Fragment>
);
}
}
Paginate.propTypes = {
totalRecords: PropTypes.number.isRequired,
pageLimit: PropTypes.number,
pageNeighbours: PropTypes.number,
onPageChanged: PropTypes.func,
};
export default Paginate;
CodePudding user response:
The data object passed to onPageChanged
doesn't have a selected
field, use data.currentPage
instead
const currentPage = data.currentPage;