我为什么要“返回_this.state.data”而不是JSON对象

我有一个父组件正在执行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);
  };
最佳答案
首先,是的,您应该将发送到InfoList的数据属性更改为this.state.data而不是匿名函数.因此:< InfoList data = {this.state.data} />

但是,主要问题是在子组件中使用componentDidMount,而实际上应该使用componentWillReceiveProps代替.

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

在初始渲染之前,componentDidMount生命周期挂钩被调用了一次.

在子组件的componentDidMount上,您尝试记录this.state.data-但此状态基于构造函数中设置的内容,即在您首次安装InfoList时作为数据属性传入的内容.那是[],因为InfoBox尚未从其Ajax调用接收回数据.换一种方式:

InfoList.componentDidMount() fired before InfoBox.loadDonationsFromServer() got back its response. And InfoList.componentDidMount() does not get fired again.

每当道具更改时,都会调用componentWillReceiveProps

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

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

额外资源

>这是一个helpful article,几乎描述了您面临的相同问题.
> React生命周期挂钩的绝佳快速参考是React Cheat Sheet)

相关文章

kindeditor4.x代码高亮功能默认使用的是prettify插件,prett...
这一篇我将介绍如何让kindeditor4.x整合SyntaxHighlighter代...
js如何实现弹出form提交表单?(图文+视频)
js怎么获取复选框选中的值
js如何实现倒计时跳转页面
如何用js控制图片放大缩小