使用Reactjs

时间:2017-08-23 13:17:16

标签: javascript json reactjs

我正在尝试创建一个订单表。我使用React + Redux。 我的数据存储在道具中。 数据的结构类似于:(更详细一点)

[{ //stored in props(redux state)
      "id": 37, //order 1
      "content": {
        "items": {
          "47427": {
            "price": "12.49",
            "format": "[\"1x12\"]",
            "quantity": 1,
          },
           "23451": {
            "price": "18.99",
            "format": "[\"1x7\"]",
            "quantity": 1,
          },
        }
      },
      "address": {
        "first_name": "Tyrion",
        "last_name": "Lannister",
        "line1": "The Red Keep",
        "city": "King's Landing",
        "country": "Westeros",
      }
    }, {
      "id": 38, //order 2
      "content": {
        "items": {
          "183429": {
            "price": "8.99",
            "format": "[\"1x7\"]",
            "quantity": "1",
          }
        }
      },
      "address": {
        "first_name": "Arya",
        "last_name": "Stark",
        "line1": "23 Wolf st.",
        "city": "Winterfell",
        "country": "Westeros",
      }
    }, {
      "id": 30, //order 3
      "content": {
        "items": {
          "20399": {
            "price": "21.99",
            "format": "[\"1x12\"]",
            "quantity": 1,
          }
        }
      },
      "address": {
        "first_name": "Jon",
        "last_name": "Snow",
        "line1": "29 Winter is here st.",
        "city": "The Wall",
        "country": "Westeros",
      }
    }]

我想访问每个订单的“内容”和“地址”属性,并将其显示在表格中。所以我试图在这个对象上调用orders.map(),但这只能让我访问第一层属性 - 例如order.id。 当我尝试访问order.content.item.price时,我收到错误“无法读取未定义的属性”。

我的问题是关于order.content.items。那时我有另一个迭代的对象,因为它有不同的属性名称,包含其中的属性(.price,.format,.quantity)。 所以基本上,我如何处理这些复杂的数据,所以我可以抓住这个对象中的每一条信息并将它们放在我的表中?

    //my render function of <OrdersTable />
    render() {
        let filter = this.props.filter || {};
        let orders = this.props.orders || []; 
        let content = orders.map(order => {
            return (
                <tr key={order.id}>
                    <td>{order.content}</td>
                </tr>
            )
        })
        let address = orders.map(order => {
            return (
                <tr key={order.id}>
                    <td>{order.address.first_name}</td>
                </tr>
            )
        })
        return (
            <div>
                <button className="filter"
                        onClick={this.props.showContent}>
                    Show Content
                </button>
                <button className="filter"
                        onClick={this.props.showAddress}>
                    Show Address
                </button>
                <table className='orders'>
                    <thead className={filter.showContent?'content': 'content hidden'}>
                        <tr>
                            <th>Items</th>
                            <th>Format</th>
                            <th>Quantity</th>
                            <th>Price</th>
                        </tr>
                    </thead>
                    <thead className={filter.showAddress?'address': 'address hidden'}>
                        <tr>
                            <th>First Name</th>
                            <th>Last Name</th>
                            <th>Country</th>
                            <th>City</th>
                        </tr>
                    </thead>
                    <tbody className={filter.showContent?'content': 'content hidden'}>
                       {content}
                    </tbody>
                    <tbody className={filter.showAddress?'address': 'address hidden'}>
                       {address}
                    </tbody>
                </table>
            </div>
        )

非常感谢:)

修改的: 所以这就是我的案例中的诀窍:(在@ TW80000和@TomDavies的帮助下)

       let content = orders.map(order => {
                const items= Object.keys(order.content.items).map(id => {
                   const item= order.content.items[id];
                   return(
                     <tr key={id}>
                        <td>{id}</td>
                        <td>{item.format}</td>
                        <td>{item.quantity}</td>
                        <td>{item.price}</td>
                     </tr>
                  )
              })
            return items;
        });
        const address = orders.map(order => {
            return (
                <tr key={order.id}>
                    <td>{order.address.first_name}</td>
                    <td>{order.address.last_name}</td>
                    <td>{order.address.country}</td>
                    <td>{order.address.state}</td>
                    <td>{order.address.city}</td>
                    <td>{order.address.line1}</td>
                    <td>{order.address.zip}</td>
                </tr>
            )
        });

...

    <tbody className={filter.showContent?'content': 'content hidden'}>
                       {content}
                    </tbody>
                    <tbody className={filter.showAddress?'address': 'address hidden'}>
                       {address}
                    </tbody>

2 个答案:

答案 0 :(得分:0)

  

我想访问每个订单的“内容”和“地址”属性,并将其显示在表格中。

你到处乱拼地址错误,这可能就是为什么它没有被正确读出。

  

所以我试着在这个对象上调用orders.map(),但这只能让我访问第一层属性 - 例如order.id。

事实并非如此,您可以访问所有媒体资源:idaddresscontent

  

当我尝试访问order.content.item.price时,我收到错误“无法读取未定义的属性”。

那是因为它是content.items带有“s”,而不是content.item就像你写的那样。 content.item未定义,这就是您收到此错误的原因。

  

我的问题是关于order.content.items。那时我有另一个迭代的对象,因为它有不同的属性名称,包含其中的属性(.price,.format,.quantity)。

您可以执行嵌套循环。例如:

let content = orders.map(order => {
  const tds = Object.keys(order.content.items).map(id => {
    const item = order.content.items[id];
    // You can use item.quality and item.format here as well
    return(<td>{item.price}</td>);
  })
  return (
    <tr key={order.id}>{tds}</tr>
  );
})

答案 1 :(得分:0)

由于您正在处理复杂的数据,我宁愿将所有内容分成小的子组件,以便以后更容易使用和理解代码。

// Only order details
const OrderRow = (order) => {
  return (
    <tr>
      {
        Object.keys(order.content.items).map((key, index) => {
          const item = order.content.items[key]
          return (
            <td key={index}>{item.price} {item.format} {item.quantity}</td>
          )
        })
      }
    </tr>
  )
}

// Only address details 
const AddressRow = (address) => {
  return (
    <tr>
      <td>{adress.first_name}</td>
    </tr>
  )
}


// In your main component, render them all 
render() {
  ...

  return (
    <table>
      ...
      <tbody>
        {orders.map(order => <OrderRow key={order.id} order={order} />)}
      </tbody>
      <tbody>
        {orders.map(order => <AddressRow key={order.id} address={order.address} />)}
      </tbody>
    </table>
  )
}