与用户映射多个地址json react js

时间:2018-12-18 18:31:11

标签: json reactjs

我正在尝试构建具有2个JSON文件的ReactJS API。

  • 第一个文件包含所有用户
  • 第二个文件包含用户的所有地址。

这是两个JSON的代码段。

Users.json

{
  "User": [
    {
      "BossId": "3",
      "DateOfBirth": "1966-09-27T00:00:00",
      "FamilyName": "Montejano",
      "Gender": "Unspecified",
      "GivenName": "Trinh",
      "Id": "8",
      "Title": "Tech Manager"
    },
    {
      "BossId": null,
      "DateOfBirth": "1927-01-29T00:00:00",
      "FamilyName": "Fetzer",
      "Gender": "Unspecified",
      "GivenName": "Winfred",
      "Id": "1",
      "Title": "CEO"
    },
]
}

Address.json

{
  "StreetAddress": [
    {
      "Id": 1,
      "PersonId": 1,
      "Street": "62 Durham Court",
      "City": "Garfield",
      "State": "NJ",
      "Zip": "07026"
    },
    {
      "Id": 2,
      "PersonId": 1,
      "Street": "179 Cambridge Court",
      "City": "Chippewa Falls",
      "State": "WI",
      "Zip": "54729"
    },
  ]
}

如何映射用户及其地址?

这是我按照答案中的建议进行操作的当前方式。

import React from "react";

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      users: [],
      adresses: []
    };
  }
  componentDidMount() {
    import("./data/PersonData").then(users => {
      this.setState({ users });
    });
    import("./data/StreetAddress").then(adresses => {
      this.setState({ adresses });
    });

    const result = this.state.users.map(user => ({
      ...user,
      adresses: this.state.adresses.filter(adr => adr.PersonId === user.Id)
    }));
    console.log(result);
  }
  render() {

    return <div className="App"></div>;
  }
}

export default App;

,我在控制台中得到一个空数组。这是我正在寻找的输出

{
    "User": {
        "Id" : "1",
        "FirstName" : "Winfred",
        "LastName" : "Fetzer",
        "BossName" : null,
        "Title" : "CEO",
        "DateOfBirth" : "1927-01-29",
        "Gender" : "Female",
        "Addresses" : [{
            "Id" : 1,
            "Street" :  "62 Durham Court",
            "City" : "Garfield",
            "State" : "NJ",
            "Zip" : "07026"
        },{
            "Id" : 2,
            "Street" :  "179 Cambridge Court",
            "City" : "Chippewa Falls",
            "State" : "WI",
            "Zip" : "54729"
        },{
            "Id" : 3,
            "Street" :  "573 Route 5",
            "City" : "Memphis",
            "State" : "TN",
            "ZipCode" : "38106"
        }]
    }
}

2 个答案:

答案 0 :(得分:1)

您可以通过以下方式映射它:

const adresses =  [
    {
        "Id": 1,
        "PersonId": 1,
        "Street": "62 Durham Court",
        "City": "Garfield",
        "State": "NJ",
        "Zip": "07026"
    },
    {
        "Id": 2,
        "PersonId": 1,
        "Street": "179 Cambridge Court",
        "City": "Chippewa Falls",
        "State": "WI",
        "Zip": "54729"
    },
]

const users = [
    {
        "BossId": "3",
        "DateOfBirth": "1966-09-27T00:00:00",
        "FamilyName": "Montejano",
        "Gender": "Unspecified",
        "GivenName": "Trinh",
        "Id": "8",
        "Title": "Tech Manager"
    },
    {
        "BossId": null,
        "DateOfBirth": "1927-01-29T00:00:00",
        "FamilyName": "Fetzer",
        "Gender": "Unspecified",
        "GivenName": "Winfred",
        "Id": "1",
        "Title": "CEO"
    },
]

const result = {
    Users: users.map(user => ({
        ...user,
        adresses: adresses.filter(adr => adr.PersonId == user.Id).map(({ PersonId, ...rest }) => rest)
    }))
}

console.log(result)

您的地址ID似乎是数字,而您的人的ID则是字符串,这就是为什么我使用==运算符

编辑:

如果每个用户可能有多个地址,则上述方法很好。 addresses.filter(..)将创建一个新数组,其中包含具有此人ID的所有地址。

如果您只希望每人一个地址,则可以改用addresses.find(...)

const result = users.map(user => ({
    ...user,
    adresses: adresses.find(adr => adr.PersonId == user.Id)
}))

您收到一个空数组,因为您正在等待数据加载:

    import("./data/PersonData").then(users => {
      this.setState({ users });
    });

执行此操作将不会等待文件导入,即使您的变量处于该状态,唯一可再次调用的函数是render,现在可以访问您的变量。您可以通过3种方式解决此问题:

1-等待进口,尽管这可能被视为不良做法:

componentDidMount = async() {
    const users = await import("./data/PersonData")
    const adresses = await import("./data/StreetAddress")

    const result = users.map(user => ({
      ...user,
      adresses: adresses.filter(adr => adr.PersonId === user.Id)
    }));
    console.log(result);
}

2-在全班开始时导入文件:

import React from "react";
import users from "./data/PersonData.json"
import adresses from "./data/StreetAddress.json"

class App extends React.Component {

3-在渲染功能中使用数据:

componentDidMount() {
    import("./data/PersonData").then(users => {
      this.setState({ users });
    });
    import("./data/StreetAddress").then(adresses => {
      this.setState({ adresses });
    });
  }

  render() {
    const result = this.state.users.map(user => ({
      ...user,
      adresses: this.state.adresses.filter(adr => adr.PersonId === user.Id)
    }));
    console.log(result);
    return <div className="App"></div>;
  }

对于您而言,我认为第二种解决方案更适合您的需求

现在,新的映射:

const result = {
    Users: users.map(user => ({
        ...user,
        adresses: adresses.filter(adr => adr.PersonId == user.Id).map(({ PersonId, ...rest }) => rest)
    }))
}

现在您的PersonId将不会包含在地址中

答案 1 :(得分:0)

只需将User的{​​{1}}映射到Id的{​​{1}}:

StreetAddress
PersonId