React:渲染嵌套json数据时遇到麻烦

时间:2019-12-31 03:26:57

标签: javascript arrays reactjs dictionary key

我在本地服务器上运行了一个嵌套的json,我试图通过能够输出此嵌套数据来练习React。对于这个,我试图仅显示日期并输出白天的可用时隙。我正处于尝试输出每个“插槽”的阶段,并将使用按钮/切换放置更多功能。

使用以下代码,我只能了解我认为正在获取的“日子”(星期一,星期二...)。如果我错了,请指正我,但是我认为它们仅被解析为字符串,而不是作为对象或数组进行维护,因此我不会注意到我可以获取“插槽”。另一个证据是,当我尝试映射“天”时,它是在映射字符串。

我认为我的问题是,当道具沿组件树传递时,我还不了解并无法追踪道具。教程和指南解释了一般的映射感,但总体而言,我要么失去了维护道具的特定细节,要么总体上就错了。

另外,您可能会说,这是我在互联网上的第一篇与代码相关的文章。我也想请您提示有关编码的问题或提供有用的供稿(或喜欢小偷小摸)。我想更多地参与这些资源来测试/练习我对其他人的问题的了解。

当然,nit-pick是任何首选的react语法。我只有一星期大,并试图吸收尽可能多的有关反应的信息。

json

const advisor = [
    {
      id: 2,
      name: { first: "John", last: "Doe" },
      email: "jdoe@harvard.edu",
      availability: {
        monday: {
          slot: { start: 1400, end: 1410, available: true, student: null },
          slot: { start: 1415, end: 1425, available: true, student: null },
          slot: { start: 1430, end: 1440, available: false, student: null },
          slot: { start: 1445, end: 1455, availabie: true, student: null }
        },
        tuesday: {},
        wednesday: {},
        thurday: {
          // slot1: { start: 1400, end: 1410, available: true, student: null },
          // slot2: { start: 1415, end: 1425, available: true, student: null },
          // slot3: { start: 1430, end: 1440, available: true, student: null },
          // slot4: { start: 1445, end: 1455, availabie: true, student: null }
        },
        friday: {}
      }
    }
  ];

应用

import React from "react";
import Advisors from "./components/advisors/advisors.jsx";

function App() {
  return (
    <div className="App">
      <Advisors />
    </div>
  );
}

export default App;

顾问

import React, { Component } from "react";
import Availability from "./availability/availability.jsx";

class Advisors extends Component {
  constructor(props) {
    super(props);
    this.state = {
      advisors: []
    };
  }

  componentDidMount = () => {
    this.fetchData();
  };

  fetchData = () => {
    fetch("/api/advisors")
      .then(response => response.json())
      .then(
        advisors => this.setState({ advisors })
      )
      .catch(error => console.log("Parse Failed", error));
  };

  render() {
    const { advisors } = this.state;

    return (
      <div>
        {advisors.map(advisor => {

          return (
            <div key={advisor.id}>
              <h2>
                {advisor.name.first} {advisor.name.last}
              </h2>
              <h6>{advisor.email}</h6>
              {Object.keys(advisor.availability).map((day, key) => (
                //keys = {mon, tues, wed, thu, fri}
                <Availability key={key} day={day} />
              ))}
            </div>
          );
        })}
      </div>
    );
  }
}

export default Advisors;

可用性

import React, { Component } from "react";

class Availability extends Component {
  constructor(props) {
    super(props);
    this.state = {};
  }

  render() {
    const { day } = this.props;

    return (
      <div>
        <h4>{day}</h4>
        <ul>
          {Object.keys(day).map((x, i) => {
            return <li key={i}>{x.start}</li>;
          })}
        </ul>
      </div>
    );
  }
}

export default Availability;

2 个答案:

答案 0 :(得分:0)

问题在于您传递道具的方式。注意这一行

Object.keys(advisor.availability).map((day, key) => (
   //keys = {mon, tues, wed, thu, fri}
   <Availability key={key} day={day} />
))

Object.keys(advisor.availability)返回数组[mon, tues, wed, thu, fri]。现在,在arr.map((day,key)=>{})中,day逐个取值mon,tues,wed,etc.,这是一个字符串,您将其作为对<Availability/>的支持而传递

为了传递值对象,它应该是

Object.keys(advisor.availability).map((day, key) => (
   <Availability key={key} day={advisor.availability[day]} />
))

现在,您的advisor对象中还有另一个问题。注意monday键在对象中。它具有多次相同的密钥slot,这在JS对象中是不允许的,因此JS会将其替换为最后一个插槽,最后您只有一个插槽。

monday: {
  slot: { start: 1400, end: 1410, available: true, student: null },
  slot: { start: 1415, end: 1425, available: true, student: null },
  slot: { start: 1430, end: 1440, available: false, student: null },
  slot: { start: 1445, end: 1455, availabie: true, student: null }
}

您可以通过两种方式(可能更多)对其进行修复。

  1. 将密钥更改为slot1,插槽2等。例如,
monday: {
  slot1: { start: 1400, end: 1410, available: true, student: null },
  slot2: { start: 1415, end: 1425, available: true, student: null },
  slot3: { start: 1430, end: 1440, available: false, student: null },
  slot4: { start: 1445, end: 1455, availabie: true, student: null }
}

并在Availability.js中替换此代码

{Object.keys(day).map((x, i) => {
  return <li key={i}>{x.start}</li>;
})}

与此

{Object.keys(day).map((x, i) => {
  return <li key={i}>{day[x].start}</li>;
})}
  1. 另一种方法是将其定义为数组。例如。
monday: [
  { start: 1400, end: 1410, available: true, student: null },
  { start: 1415, end: 1425, available: true, student: null },
  { start: 1430, end: 1440, available: false, student: null },
  { start: 1445, end: 1455, availabie: true, student: null }
]

并在Availability.js中替换此代码

{Object.keys(day).map((x, i) => {
  return <li key={i}>{x.start}</li>;
})}

与此

{day.map((x, i) => {
  return <li key={i}>{x.start}</li>;
})}

答案 1 :(得分:0)

您必须将availability的键和值都传递到子< Availability />组件中。

首先,您应该确保HTTP请求中availability对象内的键是唯一的。当前,它们都有相同的密钥slot。您可以考虑将名称更改为slot1slot2等。

const advisor = [
    {
      id: 2,
      name: { first: "John", last: "Doe" },
      email: "jdoe@harvard.edu",
      availability: {
        monday: {
          slot1: { start: 1400, end: 1410, available: true, student: null },
          slot2: { start: 1415, end: 1425, available: true, student: null },
          slot3: { start: 1430, end: 1440, available: false, student: null },
          slot4: { start: 1445, end: 1455, availabie: true, student: null }
        },
        // others
      }
    }
  ];

这是您需要更改的上级Advisors组件。如您所见,您将需要将整个availability对象传递到您的子组件中,以便可以渲染数据。

{Object.keys(advisor.availability).map((day, key) => (
  <Availability key={key} day={day} availability={advisor.availability[day]}/>
))}

在您的孩子Availability组件上,

您将需要映射并渲染作为道具传递给它的可用性开始时间。

<ul>
  {Object.keys(availability).map((x, i) => {
    return <li key={i}>{availability[x].start}</li>;
  })}
</ul>

我在这里创建了一个demo