React API 调用未按预期使用 setState()
React API call is not working as intended with setState()
所以我在这里按页获取记录。在安装时,我获取了第 1 页,然后在下一个和上一个按钮上我正在更改计数,这正在更改页码并发出获取请求。但是我的代码无法正常工作。它为我提供了计数先前状态的结果。
App.js
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
data: {},
count: 1,
};
}
handleApi = () => {
fetch(`http://localhost:9000/accounts?page=${this.state.count}`)
.then((res) => res.json())
.then((res) => {
this.setState({ data: res });
})
.catch((err) => console.log(err));
};
handlePrev = () => {
if (this.state.count > 1) {
this.setState((prevState) => ({
count: prevState.count - 1
}))
this.handleApi();
}
};
handleNext = () => {
if (this.state.count < this.state.data.total) {
this.setState((prevState) => ({
count: prevState.count + 1
}))
this.handleApi();
}
};
componentDidMount() {
this.handleApi();
}
render() {
return (
<div className="App container">
<h1 className="mb-3 text-center">Pagination Homepage</h1>
{Object.keys(this.state.data).length !== 0 ? (
<ListData detail={this.state.data} />
) : (
<h4 className="mb-5 text-center">No Data to Show.</h4>
)}
<nav aria-label="Page navigation example">
<ul className="pagination justify-content-center mt-4">
<li className="page-item">
<button
className="btn btn-outline-primary me-3"
onClick={this.handlePrev}
>
Prev
</button>
</li>
<li className="page-item">
<button
className="btn btn-outline-success"
onClick={this.handleNext}
>
Next
</button>
</li>
</ul>
</nav>
</div>
);
}
}
export default App;
ListData.js
export default class ListData extends Component {
render() {
return (
<div className="list-outer">
<h4 className="mb-3 text-center"> List Data</h4>
<div className="list-head">
<p>Name</p>
<p>E-mail</p>
</div>
{this.props.detail.data &&
this.props.detail.data.map((list, index) => (
<div key={list._id} className="list">
<p className="list-item">{list.name.toUpperCase()} </p>
<p className="list-item"> {list.mail}</p>
</div>
))}
</div>
);
}
}
控制台
更新计数后,API 仍在调用计数的先前状态。
这里数据中的页码应该等于计数。
由于 setState 以异步方式工作,调用 setState 后 this.state 变量不会立即更改。因此,如果您想在状态变量上设置状态然后 return 结果后立即执行操作,请使用回调:
handlePrev = () => {
if (this.state.count > 1) {
this.setState((prevState) => ({
count: prevState.count - 1
}), () => this.handleApi());
}
};
handleNext = () => {
if (this.state.count < this.state.data.total) {
this.setState((prevState) => ({
count: prevState.count + 1
}), () => this.handleApi());
}
};
所以我在这里按页获取记录。在安装时,我获取了第 1 页,然后在下一个和上一个按钮上我正在更改计数,这正在更改页码并发出获取请求。但是我的代码无法正常工作。它为我提供了计数先前状态的结果。
App.js
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
data: {},
count: 1,
};
}
handleApi = () => {
fetch(`http://localhost:9000/accounts?page=${this.state.count}`)
.then((res) => res.json())
.then((res) => {
this.setState({ data: res });
})
.catch((err) => console.log(err));
};
handlePrev = () => {
if (this.state.count > 1) {
this.setState((prevState) => ({
count: prevState.count - 1
}))
this.handleApi();
}
};
handleNext = () => {
if (this.state.count < this.state.data.total) {
this.setState((prevState) => ({
count: prevState.count + 1
}))
this.handleApi();
}
};
componentDidMount() {
this.handleApi();
}
render() {
return (
<div className="App container">
<h1 className="mb-3 text-center">Pagination Homepage</h1>
{Object.keys(this.state.data).length !== 0 ? (
<ListData detail={this.state.data} />
) : (
<h4 className="mb-5 text-center">No Data to Show.</h4>
)}
<nav aria-label="Page navigation example">
<ul className="pagination justify-content-center mt-4">
<li className="page-item">
<button
className="btn btn-outline-primary me-3"
onClick={this.handlePrev}
>
Prev
</button>
</li>
<li className="page-item">
<button
className="btn btn-outline-success"
onClick={this.handleNext}
>
Next
</button>
</li>
</ul>
</nav>
</div>
);
}
}
export default App;
ListData.js
export default class ListData extends Component {
render() {
return (
<div className="list-outer">
<h4 className="mb-3 text-center"> List Data</h4>
<div className="list-head">
<p>Name</p>
<p>E-mail</p>
</div>
{this.props.detail.data &&
this.props.detail.data.map((list, index) => (
<div key={list._id} className="list">
<p className="list-item">{list.name.toUpperCase()} </p>
<p className="list-item"> {list.mail}</p>
</div>
))}
</div>
);
}
}
控制台
更新计数后,API 仍在调用计数的先前状态。
这里数据中的页码应该等于计数。
由于 setState 以异步方式工作,调用 setState 后 this.state 变量不会立即更改。因此,如果您想在状态变量上设置状态然后 return 结果后立即执行操作,请使用回调:
handlePrev = () => {
if (this.state.count > 1) {
this.setState((prevState) => ({
count: prevState.count - 1
}), () => this.handleApi());
}
};
handleNext = () => {
if (this.state.count < this.state.data.total) {
this.setState((prevState) => ({
count: prevState.count + 1
}), () => this.handleApi());
}
};