首页 > 解决方案 > 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 上进行测试时,该表也显示为空白。

我已经尝试了几种不同的方法来尝试解决这个问题,但我一直在回想同样的问题。以下是我尝试过的一些事情:

  1. 使用 for 循环编写一个备用函数来迭代 this.state 中的数组——我能够记录状态,但是当尝试访问 for 循环中的元素时,循环表现得好像数组是空的。
  2. 在构造函数中使用 map 和替代函数,以及其他函数,例如 componentDidMount(我认为现在已经过时,但我还是尝试了)、componentWillMount 等。
  3. 我尝试在构造函数中构建 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>
    );
}

我没有收到任何错误消息,我只是看到一张空桌子——提前感谢您的想法和反馈!

标签: javascriptarraysreactjs

解决方案


问题

构造函数是同步的,因此它不能也不会等待获取的数据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>;
  }
}

推荐阅读