javascript - React - 有一个列表,但不能用它做任何事情
问题描述
我正在处理一个由几个页面组成的 React 组合,一个主页、个人资料、项目列表和联系页面。对于投资组合的这一部分,它旨在显示我的 Github 存储库的数组。
我在与数组交互时遇到问题——它的行为很奇怪,而且我已经坚持了好几天了。我可以从控制台打印状态下的数组,但是当我尝试用它做任何事情时,它的行为就好像它是空的。
例如(放置在 render() 中的测试):
console.log(this.state.repos); //Prints out array of repos, as expected
console.log(`Repos: ${this.state.repos)}`); //Prints string, no array
真正令人烦恼的是,预期的结果似乎出现在卸载时——当我对 RepoTable 或 Repo 进行小编辑并保存源文件时,当它在 localhost 上重新加载时,表出现,并且我希望在安慰。当我点击刷新时,一切都消失了,当我将它部署到 Heroku 上进行测试时,该表也显示为空白。
我已经尝试了几种不同的方法来尝试解决这个问题,但我一直在回想同样的问题。以下是我尝试过的一些事情:
- 使用 for 循环编写一个备用函数来迭代 this.state 中的数组——我能够记录状态,但是当尝试访问 for 循环中的元素时,循环表现得好像数组是空的。
- 在构造函数中使用 map 和替代函数,以及其他函数,例如 componentDidMount(我认为现在已经过时,但我还是尝试了)、componentWillMount 等。
- 我尝试在构造函数中构建 Repo 组件列表,然后在 render() 中使用它,但它不起作用,我仍然得到一个空列表。
我也尝试了其他一些东西,但我认为我尝试过的东西基本上是做同一件事的不同方式。
这是 RepoTable 组件的代码:
class RepoTable extends Component {
constructor(props) {
super(props);
this.state = {
repos: this.get_repos()
}
}
get_repos(){
const repo_list = [];
axios
.get("https://api.github.com/users/Geno1131993/repos")
.then(function(response){
for(let i = 0; i < response.data.length; i++){
repo_list.push(response.data[i]);
}
});
return repo_list;
}
render() {
const repo_list = this.state.repos.map( (repo) => {
return (<Repo key = {repo.name} repo = {repo}></Repo>);
});
return (
<ul key="repo_table">
{repo_list}
</ul>
);
}
这是 Repo 组件的代码(random 函数为列表项分配一个随机 ID,并根据确定的名称在 CSS 中为其分配一个图标):
class Repo extends Component {
constructor(props) {
super(props);
this.state = {
repo: props.repo
}
}
random(){
let key = Math.floor((Math.random() * 5) + 1);
switch(key){
case 1:
return "lotus1";
case 2:
return "lotus2";
case 3:
return "lotus3";
case 4:
return "lotus4";
case 5:
return "lotus5";
}
return -1;
}
render() {
return (
<li key = {this.state.repo.name} className="repo">
<a href={this.state.repo.html_url} rel="noreferrer" target="_blank">
<div className="repo_title">{this.state.repo.name}</div>
<div className="repo_info">
<p id={this.random()} className="lotus"></p>
<p className="repo_description">{this.state.repo.description}</p>
</div>
</a>
</li>
);
}
我没有收到任何错误消息,我只是看到一张空桌子——提前感谢您的想法和反馈!
解决方案
问题
构造函数是同步的,因此它不能也不会等待获取的数据get_repos
解决。您的初始repos
状态不正确。您也不能进行异步调用以从内部设置初始状态,在constructor
组件安装后执行此操作并将响应实际保存到状态中。
解决方案
class RepoTable extends Component {
constructor(props) {
super(props);
this.state = {
repos: [] // <-- valid initial empty array
};
}
componentDidMount() {
this.get_repos(); // <-- fetch upon mounting
}
get_repos = async () => {
axios
.get("https://api.github.com/users/Geno1131993/repos")
.then(response => {
this.setState({
repos: response.data // <-- update state with response array
});
});
};
render() {
const repo_list = this.state.repos.map((repo) => {
return <Repo key={repo.name} repo={repo}></Repo>;
});
return <ul key="repo_table">{repo_list}</ul>;
}
}
推荐阅读
- ios - 在 Swift 中向 TabBarController 添加滑出菜单(使用 UIScrollView)
- linux - 使用 While 和 IF 进行验证
- if-statement - Google 表格中的嵌套 IF/AND 语句
- ruby-on-rails - 星期一作为 Administrate Rails 引擎提供的日期选择器中的第一天
- c - 在 C 中寻找文件位置 > 2^32
- reactjs - 使用 getDerivedStateFromProps 状态到道具
- java - Android - 自动化用户与网站的交互
- python - 转换 Pandas 数据框
- html - 如果 Li 框包含可变长度的文本,如何使它们对齐?
- php - 替换数组值以增加