在反应中,如何将对象存储在数组中并以1迭代数组索引?

时间:2018-08-13 17:56:39

标签: javascript arrays reactjs object iterator

我有一个页面,其中显示多个方框,每个方框都属于一个特定的公司。每个公司都有多个项目,每个项目都有多个版本。

方框1: 公司名称/项目名称/发行名称

方框2: 公司名称/项目名称/发行名称

我的状态定义如下:

this.state = {
  companies: [],
  projects: [],
  releases: [],
  activeProjects: []
}

在这里,我正在从数据库中获取所有数据:

componentWillMount() {
  getCompanys().then(companies => {
    const projectPromises = companies.map((company) => {
      getProjects(company).then(projects => {
        const releasePromises = projects.map((project) => {
          return getReleases(project).then(releases => {
            if(projects.length > 0 || releases > 0) {
              this.setState({
                companies: companies,
                projects: projects,
                releases: releases
              });
            }
          })
        })
      })
    });
  })
}

,它返回以下数据:

Companys:  (2) [{…}, {…}]0: {_id: {…}, company_name: "IBM", …}
Projects:  [{…}]0: {_id: {…}, project_name: "Project 101", …}
Releases:  (3) [{…}, {…}, {…}]0: {_id: {…}, release_name: "Release 103", …}

我得到2家公司,1个项目和3个版本。

如果我想将公司,项目中的每一个存储并发布到我的 activeProjects 阵列中,我将如何实现以下目标?

activeProjects: [
  {
    company: ,
    project: ,
    release: 
  },
  {
    company: ,
    project: ,
    release: 
  },
]

有人可以帮我吗?

我希望我的最终结果像这样:

activeProjects.map((project, index) => {
  return(
    **Box 1**
    IBM / Project 101 / Release Name goes here

    **Box 2**
    Facebook / Project 102 / Release Name goes here
  )
});

1 个答案:

答案 0 :(得分:0)

我建议从一开始就以所需的格式构建数据。我的意思是,不是将您的公司,项目和发行版在您所在的州分为单独的阵列,而是从一开始就保持嵌套。

(从我的代码中可以看出,每次都覆盖项目和发布,因此只剩下最后一个公司的项目和最后一个项目的发布。)

1。。第一个结构状态如下:

state = {
    companies: [],
    activeProjects: []
}

2。。然后将您的componentWillMount方法改写成这样(为了便于阅读,我也建议您使用async / await而不是回调函数)。

async componentWillMount() {
    const companies = await getCompanies();
    for (const company of companies) {
        company.projects = await getProjects(company);
        for (const project of company.projects) {
            project.releases = await getP
        }
    }

    this.setState({ companies });
}

这是一个稍微复杂但效率更高的版本,因为它可以异步地在多个公司/项目上工作,而不是在继续之前等待每个呼叫的响应:

async componentWillMount() {
    const companies = await getCompanies();
    const nestedCompanies = await Promise.all(companies.map(async company => {
        const projects = await getProjects(company);
        const nestedProjects = await Promise.all(projects.map(async project => {
            const releases = await getReleases(project);
            return {
                ...project,
                releases
            }
        }));
        return {
            ...company,
            projects: nestedProjects
        }
    }));

    this.setState({ companies: nestedCompanies });
}

现在您的状态将如下所示:

{
    companies: [
        {
            id: 1,
            name: 'IBM',
            projects: [
                {
                    id: 1,
                    name: 'Project 101',
                    releases: [
                        {
                            name: 'Release Name'
                        },
                        // and so on
                    ]
                },
                // and so on
            ]
        },
        // and so on
    ]
}

3。。现在遍历公司中的数据应该非常简单。您可以执行以下操作:

const activeProjects = this.state.companies.map(company => {
    return company.projects.map(project => {
        return project.releases.map(release => {
            return `${company.name} / ${project.name} / ${release.name}`;
        });
    }).reduce((acc, e) => acc.concat(e), []);
}).reduce((acc, e) => acc.concat(e), []);

上面的代码将导致activeProjects是字符串数组,每个字符串的格式为'IBM / Project 101 / Release Name'。对于最后一步,您可以改为返回某些组件,例如:

<Box company={ company.name } project={ project.name } release={ release.name }/>,

取决于项目的结构。