简体   繁体   English

反应:无法呈现嵌套的 json 数据

[英]React: Having trouble rendering nested json data

I have a nested json running in my local server and I'm trying to practice react by being able to output this nested data.我有一个嵌套的 json 在我的本地服务器中运行,我正在尝试通过能够输出这个嵌套数据来练习反应。 For this one, I'm trying to just show the day and output available time-slots during the day.对于这个,我试图只显示一天并输出一天中可用的时间段。 I'm at the stage of trying to reach outputting each "slot" and will be putting more features using buttons/toggles.我正处于尝试输出每个“插槽”的阶段,并将使用按钮/切换来放置更多功能。

With the following codes, I can only get up to what I think is fetching the "days"(mon,tues...).使用以下代码,我只能解决我认为获取“天”(星期一,星期二......)的问题。 Correct me if I'm wrong, but I think they're only parsed as strings instead of maintaining as objects or arrays so I don't notice that I can fetch the "slots".如果我错了,请纠正我,但我认为它们仅被解析为字符串,而不是作为对象或数组进行维护,因此我没有注意到我可以获取“插槽”。 The other evidence is that when I try to map a "day", it's mapping the string.另一个证据是,当我尝试映射“一天”时,它正在映射字符串。

I think my issue is that I haven't understood and lose track of props when it's being passed down the component tree.我认为我的问题是当 props 被传递到组件树时我没有理解并且失去了对 props 的跟踪。 The tutorials and guides explain the general sense of mapping, but I either lost a specific detail to maintain props or I'm doing something wrong with mapping, in general.教程和指南解释了映射的一般意义,但我要么丢失了维护道具的特定细节,要么我在映射方面做错了,总的来说。

Also, as you can probably tell, this is my first code-related post on the internet.此外,正如您可能知道的,这是我在互联网上的第一篇与代码相关的帖子。 I'd like to also ask for your tip of asking or giving helpful feeds with regards to coding (or like pet-peeves).我还想请教您关于编码(或喜欢惹是生非)的询问或提供有用信息的提示。 I'd like to be more involved with these resources to test/practice my knowledge with other people's problems.我想更多地参与这些资源,以测试/练习我对其他人问题的了解。

And of course, nit-pick any preferable react syntax.当然,挑剔任何更好的反应语法。 I'm only a week old in this and trying to absorb as much information about react as I can.我在这方面只有一周大,并试图尽可能多地吸收有关反应的信息。

json 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: {}
      }
    }
  ];

App应用程序

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

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

export default App;

Advisors顾问

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;

Availability可用性

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;

The issue is the way you're passing props.问题是你传递道具的方式。 Notice this line注意这一行

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

Object.keys(advisor.availability) returns the array [mon, tues, wed, thu, fri] . Object.keys(advisor.availability) [mon, tues, wed, thu, fri] Object.keys(advisor.availability)返回数组[mon, tues, wed, thu, fri] Now, in arr.map((day,key)=>{}) , day takes the values mon,tues,wed,etc.现在,在arr.map((day,key)=>{}) ,day 取值为mon,tues,wed,etc. one by one and it's a string which you're passing on as props to <Availability/>一个接一个,它是一个字符串,您将其作为道具传递给<Availability/>

In order to pass the value object, it should be为了传递值对象,它应该是

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

Now, another issue is in your advisor object.现在,另一个问题出现在您的advisor对象中。 Notice monday key in your object.注意对象中的monday键。 It's having the same key slot multiple times, which isn't allowed in a JS object so JS will replace it with the last slot and you end up having just 1 slot.它具有相同关键字slot多次,这是不是在JS对象允许所以JS会用最后一个插槽代替它,你最终不得不仅有1插槽。

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 }
}

You can fix it in two ways(maybe more).您可以通过两种方式(也许更多)修复它。

  1. Change keys to slot1, slot2, etc. Ex.,将密钥更改为 slot1、slot2 等。例如,
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 }
}

and in Availability.js , replace this code并在Availability.js ,替换此代码

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

with this有了这个

{Object.keys(day).map((x, i) => {
  return <li key={i}>{day[x].start}</li>;
})}
  1. Another way is to defined it as array.另一种方法是将其定义为数组。 Ex.前任。
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 }
]

and in Availability.js , replace this code并在Availability.js ,替换此代码

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

with this有了这个

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

You have to pass both the keys and values of availability into your child < Availability /> component.您必须将availability的键和值传递给您的子< Availability />组件。

First and foremost, you should ensure the keys within your availability object from your HTTP request are unique.首先,您应该确保来自 HTTP 请求的availability对象中的键是唯一的。 Currently, all of them have the same key, slot .目前,它们都具有相同的密钥slot You can consider changing the names to slot1 , slot2 , etc.您可以考虑将名称更改为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
      }
    }
  ];

On your parent Advisors component, this is what you need to change.在您的父Advisors组件上,这是您需要更改的内容。 As you can see, you will need to pass in the entire availability object into your child component, such that the data is available for rendering.如您所见,您需要将整个availability对象传递到您的子组件中,以便数据可用于呈现。

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

And on your child Availability component,在您的孩子Availability组件上,

you will need to map and render the availability start times that is passed into it as the props.您需要映射和呈现作为道具传递给它的可用性开始时间。

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

I have created a demo over here.我在这里创建了一个演示

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM