I am learning React and trying to call API for users using this component:
It works and I get users for page=1,
But, when I click on next button, the method next is triggered which should update page variable to '2' but it doesn't happen.
import React , {Component} from "react";
import Wrapper from "../components/Wrapper";
import axios from "axios";
import {User} from "../../classes/user";
import {Link} from "react-router-dom";
class Users extends Component {
state = {
users: []
}
page = 1
componentDidMount = async () => {
const response = await axios.get(`users?page=${this.page}`)
console.log(response)
this.setState({
users: response.data.data
})
}
next = async () => {
this.page ; // this never gets incremented
await this.componentDidMount();
}
render() {
return (
<Wrapper>
<div className="d-flex justify-content-between flex-wrap flex-md-no-wrap align-items-center pt-3 pb-2 mb-3 border-bottom">
<div className="btn-toolbar mb-2 mb-md-0">
<Link to={'users/create'} className="btn btn-sm btn-outline-secondary">Add</Link>
</div>
</div>
<div className="table-responsive">
<table className="table table-striped table-sm">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Name</th>
<th scope="col">Email</th>
<th scope="col">Role</th>
<th scope="col">Action</th>
</tr>
</thead>
<tbody>
{this.state.users.map(
(user: User) => {
return (
<tr>
<td>{user.id}</td>
<td>{user.first_name} {user.last_name}</td>
<td>{user.email}</td>
<td>{user.role.name}</td>
<td>
<div className="btn-group mr-2">
<a href="" className="btn btn-sm btn-outline-secondary">Edit</a>
<a href="" className="btn btn-sm btn-outline-secondary">Delete</a>
</div>
</td>
</tr>
)
}
)}
</tbody>
</table>
</div>
<nav>
<ul className="pagination">
<li className="page-item">
<a href="" className="page-link">Previous</a>
</li>
<li className="page-item">
<a href="" className="page-link" onClick={this.next}>Next</a>
</li>
</ul>
</nav>
</Wrapper>
)
}
}
export default Users;
No matter what page is always equal to 1:
url: 'users?page=1' in console
Why page variabel never gets incremented?
Alternatively, as suggested :
state = {
users: [],
page: 1
}
componentDidMount = async () => {
const response = await axios.get(`users?page=${this.state.page}`)
console.log(response)
this.setState({
users: response.data.data
})
}
next = async () => {
//this.page ;
this.setState({
page: this.state.page 1
})
await this.componentDidMount();
}
Also do not update page either...
CodePudding user response:
You have to put the variable page inside the state object.
You can increment the variable page like that :
this.setState({
page: this.state.page 1
})
CodePudding user response:
The thing you're missing is State concept as @devcarme mentioned. Particularly, you need to store page counter as a State, not as a variable.
I will oversimplify for learning purpose:
- Before React, when you click Next page button, you have to reload the whole page with a new URL. By only doing that, the page can have new content.
- React don't need to do that. React can "react" to that change by storing update in a State. With State, React can bring new content without reloading the whole page.
If you're not learn for maintaining codebase, I suggest you code in Functional component as it is shorter than Class component version, which make it's easier to approach.
In the long run, React dev team will focus on Functional component and keep Class component for legacy codebase. They will provide ways to update, for example React Hooks, which makes functional component mostly equivalent to class component.