Как получить глубоко вложенные данные из тела ответа в состояние - PullRequest
0 голосов
/ 04 января 2019

Я создал выставочную страницу в реакции, которая должна отображать имя выбранного ученика, инструмент (ы), на котором они играют, и их задания.

База данных (упрощенно): данные пользователя (студента)> отношение «многие ко многим» <инструмент> отношение «многие ко многим» <назначение </p>

Хотя я могу перевести объект одного пользователя (студента) в состояние и отобразить имя этого студента, доступ к соответствующим инструментам и заданиям ставит меня в тупик.

Вот как выглядит body.user при входе в консоль:

{user: {…}}
  user:
    assignments: Array(1)
      0: {id: 6, name: "Concert Cb Scale", description: "Record this 
         scale to Ensemble at the start of the …nscribe the scale if 
         your instrument requires it!", created_at: "2018-11- 
         24T22:16:51.460Z", updated_at: "2018-11-24T22:16:51.460Z"}
      length: 1
    __proto__: Array(0)
  first_name: "June"
  id: 10
  instrument_sections: Array(1)
    0: {id: 7, instrument: "french horn", created_at: "2018-11- 
       24T22:16:51.356Z", updated_at: "2018-11-24T22:16:51.356Z"}
    length: 1
    __proto__: Array(0)
  last_name: "Cenadaigh"

Кажется, я не могу добраться до body.user.instrument_sections (и отныне до instrument:). Я не пытался получить body.user.assignments, так как мне кажется, что я получу те же ошибки.

Ошибка, о которой идет речь, из консоли: «Ошибка при извлечении: объекты недопустимы как дочерний элемент React (найдено: объект с ключами {id, instrument, creation_at, updated_at}). Если вы намеревались отобразить коллекцию из детей, используйте вместо этого массив или оберните объект, используя createFragment (объект) из дополнений React. Проверьте метод рендеринга StudentShow. " Я понимаю, что у меня проблема с тем, что я указываю на объект внутри объекта пользователя, но я не понимаю, как поступить с предложениями, которые делает ошибка. Кроме того, если я попытаюсь изменить this.setState({ . . . instrumentSections: body.user.instrument_sections, чтобы включить .instrument, консоль вернется с просто undefined.

Мои дальнейшие попытки добраться до instrument произошли от:

  1. Попытка выяснить, что должно быть между body.user.instrument_sections и .instrument (если что).

  2. Как с map по body.user или в состояние student, чтобы добраться до instrument и привести его в состояние. (Со временем у меня будут начальные данные, в которых учащиеся будут иметь несколько инструментов, а не один, поэтому я буду держать это состояние в массиве.)

И, наконец, вот код, который у меня сейчас есть:

class StudentShow extends Component {
  constructor(props){
    super(props)
    this.state = {
      student: {},
      instrumentSections: [],
      assignments: []
    }
  }
  componentDidMount(){
    let studentId = this.props.params.id
    console.log(`${this.props.params.id}`)
    fetch(`/api/v1/users/${studentId}`)
    .then(response => {
      if (response.ok) {
        return response;
      } else {
        let errorMessage = `${response.status} 
        (${response.statusText})`;
        error = new Error(errorMessage);
        throw(error);
      }
    })
    .then(response => response.json())
    .then(body => {
      console.log(body);
      this.setState({ student: body.user, instrumentSections: 
        body.user.instrument_sections })
      console.log(this.state.student);
      console.log(this.state.instrumentSections);
    })
    .catch(error => console.error(`Error in fetch: ${error.message}`));
  }
  render(){
    return (
      <div className="text-center student-show">
        <h1>{this.state.student.first_name} 
          {this.state.student.last_name}</h1>
        <h2>Your section(s): </h2>
        <h4></h4>
        <h2>This week's assignment(s): </h2>
        <h4></h4>
      </div>
    )
  }
}

Ответы [ 2 ]

0 голосов
/ 31 января 2019

Я и парень, с которым я работал, не уверены, является ли это наиболее эффективным методом или он кошерен в стиле ReactionJS, но в конце концов, следующий цикл javascript и аксессуары будут работать. После .then(response => response.json()):

.then(body => { const sections = []; for(let i = 0; i < body.user.instrument_sections.length; i++){ sections.push(body.user.instrument_sections[i].instrument); };

И замените setState на это:

this.setState({ student: body.user, instrumentSections: sections)}

Итак, что происходит, когда js попадает в тело и через итерацию захватывает каждый соответствующий инструмент, который входит в массив sections, и, наконец, вы устанавливаете состояние instrumentSections равным sections.

0 голосов
/ 04 января 2019

Как вы можете видеть в своей консоли instrument_sections - это массив объектов, поэтому, чтобы получить первый инструмент, например, вы должны получить его как:
body.user.instrument_sections[0].instrument.
и вместо instrumentSections: body.user.instrument_sections попробуйте
instrumentSections: body.user.instrument_sections.slice() или
instrumentSections: Array.from(body.user.instrument_sections)
и дайте мне знать, если это решит вашу проблему.

...