首页 > 解决方案 > setState() 和 Object.keys() 通过父组件中的获取请求

问题描述

我正在尝试使用从父组件中的获取请求接收到的数据来设置状态。我收到了一组对象,每个对象都有以下键:“name”、“artist”、“url”、“cover”、“lrc”和“theme”。我正在使用 Object.keys() 映射对象数据,但我想知道如何以这种方式设置状态,以便将具有这六个键的多个对象存储在状态中,这样我的状态将如下所示:

this.state = { 数据:[{ {…},{…},{…},等等…}] }

一个大问题是我的数据 - 来自父级中的获取请求 - 没有在这个 tempComp 组件中呈现。我将数据作为道具(this.props.playlist)传递。为什么父级中获取的数据没有呈现在 tempComp 组件中,以及如何设置多个对象的状态,就像我在下面尝试使用 Object.keys() 一样?任何意见是极大的赞赏。

import React, { Component } from 'react'

class tempComp extends Component {
  constructor(props) {
    super(props);
    this.state = {
      data: [],
      audio: [{
        name: '',
        artist: '',
        url: '',
        cover: '',
        lrc: '',
        theme: ''
      }]

    }
  }

  async componentDidMount() {
    console.log('playlist in componentDidMount()', this.props.playlist) //<--- AudioPlayer data should be coming in here

    var json = this.props.playlist;
    var arr = [];
    Object.keys(json).forEach(function (key) {
      arr.push(json[key]);
    });
    arr.map(item => {
      this.setState({
        audio: [{
          name: item.name,
          artist: item.artist,
          url: item.url,
          cover: item.cover,
          lrc: item.lrc,
          theme: item.theme
        }]
      })
    })
    console.log(this.state.audio);
  }


  render() {
    return (
      <div>

      </div>
    )
  }
}


export default tempComp

这是父组件,为了澄清:


export default class PostContent extends Component {
  constructor(props) {
    super(props);
    this.state = {
      id: '',
      episodeData: [],
    }
  }

  async componentDidMount(){
    const { id } = this.props.match.params;
    const response = await fetch(`http://localhost:5000/episode/${id}/playlist`);
    const jsonData = await response.json();
    this.setState({
      episodeData: jsonData, //this is working!...
      id: id
    });
    console.log(this.state.episodeData) //...see?
  }

  render() {
    return (
      <Fragment>

      <TempComp playlist={this.state.episodeData} />

        <AudioPlayer playlist={this.state.episodeData} />
        <Link id='home-link' to='/' activeClassName='active'>Homepage</Link>
        {this.state.episodeData.map((item, i) => (
          <div key={i} className="word-content">
            <h2 className="show-title">{item.post_title}</h2>
            <div className="episode-post-content">{item.post_content}</div>
            </div>
            ))}
            <Table data={this.state.data} />
            <div className="bottom-link">
              <Link id='home-link' to='/' activeClassName='active'>Homepage</Link>
            </div>
      </Fragment>
    )
  }
}

标签: javascriptreactjs

解决方案


你在这里被 setState 的工作方式欺骗了。这是一种异步方法,这意味着它不会与您的地图一起运行。您可以使用 setTimeout 或 await ,我可以看到这是可能的,因为您componentDidMount的前缀是async. 但是,如果我可以冒昧的话,我建议您进行一些小的更改,如下所示:


const json = {
    apple: { yum: false },
    peach: { yum: true }
};

const yummyness = Object.keys(json).map(key => {
    return { yum: json[key].yum }
});

// yumminess will render:  [{ yum: false }, { yum: true }]
this.setState({ yummyness });

我在这里做了几件事:

  1. 如果数据没有变化,请将其分配给 const,您可以在此处了解更多信息

  2. Map 返回一个数组。这可以像现在这样非常方便,因此arr我没有推送到您的值,而是返回了一个对象以阻止您执行第二张地图。

  3. 最后,正如我之前提到的,setState 是异步的,而且有点滑!所以为了避免这种情况,我只是让地图做这件事,然后我把它分配给美味。

  4. 奖金回合:我用过水果,但我的大部分名字都一样。json是你的props.playlist,美味是你的arr

希望这有帮助!


推荐阅读