当我单击“下一步”按钮时,state.page将第二次更新。而且,如果我向前滚动几次并想推出新的存储库,它也只会从第二次印刷机输出。帮助修复它。在CodeSandBox上的项目:https://codesandbox.io/s/lab9rest-api-eupg0
Layout.js
import React from "react";
import axios from "axios";
import ReposList from "./ReposList";
export default class Layout extends React.Component {
constructor(props) {
super(props);
this.state = {
data: [],
page: 1,
pages: 100,
per_page: 10
};
}
searchNew() {
this.setState(() => {
return { page: 1 };
});
this.search();
}
search() {
let text = document.getElementById("search-text").value;
if (text !== "") {
let sort = document.getElementById("sort-items").value;
let sortValue = sort.split("-")[1];
let pagination =
"&page=" + this.state.page + "&per_page=" + this.state.per_page;
let url =
"https://api.github.com/search/repositories?q=" + text + pagination;
if (sort === "best-matches") url += "&order=desc";
if (sort === "most-stars") url += "&sort=" + sortValue + "&order=desc";
if (sort === "fewest-stars") url += "&sort=" + sortValue + "&order=asc";
if (sort === "most-followers")
url += "&sort=" + sortValue + "&order=desc";
if (sort === "fewest-followers")
url += "&sort=" + sortValue + "&order=asc";
if (sort === "most-forks") url += "&sort=" + sortValue + "&order=desc";
if (sort === "fewest-forks") url += "&sort=" + sortValue + "&order=asc";
console.log(this.state.page);
axios(url)
.then(response => {
if (response.data.items.length !== 0) {
this.setState(() => {
return {
data: response.data.items
};
});
} else alert("Репозиториев не найдено.");
})
.catch(error => {
alert("Не удалось обработать инструкции '" + text + "'.");
});
}
}
nextPage() {
if (this.state.page !== this.state.pages)
this.setState(state => {
return { page: state.page + 1 };
});
else
this.setState(() => {
return { page: 1 };
});
this.search();
}
changePerPage() {
let per_page = document.getElementById("per_page").value;
let pages = Math.floor(1000 / per_page);
console.log(pages);
this.setState(() => {
return { per_page: per_page, pages: pages };
});
}
changeCurrentPage(page) {
this.setState(() => {
return { page: page };
});
}
render() {
return (
<div>
<h3>Repository search</h3>
<div id="search">
<select id="sort-items" onChange={() => this.changeCurrentPage(1)}>
<option value="best-match">Best match</option>
<option value="most-stars">Most stars</option>
<option value="fewest-stars">Fewest stars</option>
<option value="most-forks">Most forks</option>
<option value="fewest-forks">Fewest forks</option>
<option value="most-followers">Most followers</option>
<option value="fewest-followers">Fewest followers</option>
</select>
<input type="text" id="search-text" />
<button onClick={() => this.searchNew()}>Search</button>
</div>
<div id="settings">
<p>output amount</p>
<input
type="number"
min="1"
defaultValue="10"
max="100"
id="per_page"
onChange={() => this.changePerPage()}
/>
</div>
<ReposList data={this.state.data} />
<div id="pagination">
{this.state.page}
<button onClick={() => this.nextPage()}>Next</button>
</div>
</div>
);
}
}
RepoList.js
import React from "react";
import Repo from "./Repo";
export default class ReposList extends React.Component {
render() {
return (
<div id="repos">
{this.props.data.map((repo, index) => {
return (
<Repo
key={index}
avatar={repo.owner.avatar_url}
login={repo.owner.login}
url={repo.url}
name={repo.name}
/>
);
})}
</div>
);
}
}
Repo.js
import React from "react";
export default function Repo(props) {
return (
<div className="repo">
<img src={props.avatar} alt="avatar" />
<p className="login">{props.login}</p>
<a className="url" href={props.url}>
{props.name}
</a>
</div>
);
}
答案 0 :(得分:2)
实际上,您的状态是在第一次点击时更新的-但稍后会更新。
setState
不是现在更改this.state
的同步操作,但只要有时间重新渲染,就会执行 。
因此,当您在this.search()
之后直接调用this.setState
时,this.state
尚未更新,您将继续使用旧值。
setState actuall accepts a callback作为第二个参数,因此要确保仅在状态持续存在之后才调用this.search
,您可以这样做
searchNew() {
this.setState(() => {
return { page: 1 };
},
() => this.search()
);
}