为什么我得到“ return _this.state.data”而不是JSON对象

时间:2019-02-27 01:39:32

标签: javascript json ajax reactjs

我有一个父组件在进行AJAX调用以获取JSON对象。我已经做了一些console.log来确保父组件中的数据是正确的,但是当我通过道具时,我得到的值是:

ƒ data() {
  return _this.state.data;
}

到目前为止,我所做的事情似乎很简单,所以我找不到问题所在。

父组件:

class InfoBox extends Component {
  state = {
    data: []
  };

  componentDidMount = () => {
    this.loadDonationsFromServer();
    setInterval(this.loadDonationsFromServer, this.props.pollInterval);
  };

  loadDonationsFromServer = () => {
    $.ajax({
      url: "https://jsonplaceholder.typicode.com/comments",
      dataType: "json",
      cache: false,
      success: data => {
        this.setState({ data });
      },
      error: (xhr, status, err) => {
        console.error(status, err.toString());
      }
    });
  };

  render = () => {
    return (
      <React.Fragment>
        <h1>Information</h1>
        <InfoList
          data={() => this.state.data}
        />
      </React.Fragment>
    );
  };
}

export default DonationBox;

子组件:

class InfoList extends Component {
  constructor(props) {
    super(props);
    this.state = {
      data: this.props.data
    };
  }

  componentDidMount() {
    console.log(this.state.data);
    //logs: ƒ data() {
    //         return _this.state.data;
    //      }
  }
  render() {    
    return <div> Placeholder </div>;
  }
}

export default InfoList;

我尝试在子组件中使用bind,但仍然得到了相同的东西:

  constructor(props) {
    super(props);
    this.state = {
      data: this.props.data
    };
    this.checkData = this.checkData.bind(this);
  }

  componentDidMount() {
    this.checkData();
  }

  checkData = () => {
    console.log(this.state.data);
  };

2 个答案:

答案 0 :(得分:1)

这是因为传入的data道具是一个函数。

更改

<InfoList data={() => this.state.data} />

<InfoList data={this.state.data} />

仅此而已,您实际上并不需要子组件中的构造函数来定义状态。只需按照您在父组件中的方式进行定义即可。

答案 1 :(得分:1)

首先,,您应该将发送给data的{​​{1}}道具更改为InfoList,而不是匿名功能。因此:this.state.data

但是,主要问题是在子组件中使用<InfoList data={this.state.data} />,而实际上您应该改用componentDidMount


componentDidMount仅被调用一次,它不会等待您的AJAX

componentWillReceiveProps生命周期挂钩在初始componentDidMount之前被调用了一次。

在子组件的render中,您尝试登录componentDidMount-但此状态基于在构造函数中设置的值,即在this.state.data中传递的内容首次安装data时显示prop。那是InfoList,因为[]尚未从其Ajax调用接收回数据。换句话说:

  

InfoBoxInfoList.componentDidMount()获得回应之前被解雇。 InfoBox.loadDonationsFromServer()不会不会再次被解雇。

每当道具更改时,就会调用

componentWillReceiveProps

相反,您的子组件应该使用InfoList.componentDidMount()生命周期挂钩。每当组件接收到新的道具时,就会调用此方法。一旦父母的状态发生变化(在负荷捐赠返回之后),它将新的道具传递给孩子。在componentWillReceiveProps中,孩子可以使用这些新道具并更新其状态。


我创建了一个code sandbox,它通过一系列日志语句向您显示生命周期中各个时间点的情况以及道具和状态。与实际执行ajax提取不同,我只是等待2秒钟以模拟提取。在componentWillReceiveProps中,InfoList.js的代码当前已被注释掉;这样,您可以了解事物的现状。删除注释并开始使用componentWillReceiveProps后,您将看到它们如何修复。


其他资源