componentWillMount在渲染之前没有完成

时间:2016-12-09 19:44:33

标签: reactjs react-jsx

我在反应状态方面面临一些困难。 据我所知,componentWillMount是一个在组件被渲染之前用ajax调用加载数据的地方。 我有一个简单的简单项目,它使用加载的数据填充堆栈,并在板上显示。但是,在渲染组件之前,来自ajax调用的数据不会被设置,这会导致使用空数组渲染板。以下是我的完整资料来源:

import  React from "react";
export class Panel extends  React.Component{
render() {
    return (
    <div>
        <div className="row panel">
            <div className="col-sm-12 header">sfsfsf</div>
            <div className="col-sm-12 body">fsdfsfs</div>
            <div className="col-sm-12 footer">fasfaf</div>
        </div>
    </div>
    );
   }
   }

和作为问题根源的Board类如下:

import  React from "react";
 import {Panel} from "./Panel";
 export class Board extends  React.Component{
 constructor(props){
    super();
    this.state={news: []};
}
componentWillMount(){
    this.state={news: []};
    $.ajax({
        url: "http://localhost:3003/json.txt",
        dataType: 'json',
        cache: false,
        success: function(data) {
            var arr=[];
            for (var key in data) {
                arr.push(data[key]);
                console.log(data[key]);
            }
            this.state={news: arr};
        }});
     }
     render() {
    return (
        <div>
            {
                this.state.news.map((item,i)=> <Panel key="i"/>)
            }
        </div>
    );
    }
 }

最后一个类也是index.js:

import React from "react";
 import {render} from "react-dom";
import {Board} from "./component/Board";

class App extends React.Component{

  render(){
    return(
        <div>

            <Board/>

        </div>

    );
  }

}

 render(<App/>, document.getElementById('middle'));

因此,您可以在Board.js类中看到我在渲染函数中初始化我的数组,然后我使用componentWillMount来填充新闻数组,我希望它在componentWillMount完成后发生,但在我的情况下,数组是空的渲染发生。有什么想法吗?

********* UPDATE ***************

我也尝试过使用componentDidMount,但它没有用,也没有同样的问题

2 个答案:

答案 0 :(得分:4)

componentWillMount()在渲染之前完成,但因为ajax是异步的,所以在请求完成之前它不会执行。

您不应使用this.state = ...设置状态。而是使用:

this.setState({news: arr});

这将设置值并触发组件和所有要渲染的子项。只需编写渲染函数即可很好地处理空数据,并且您可以在不阻止JS执行的情况下获得预期的结果。

正如这里建议的那样,它具有适当的约束力:

import  React from "react";
import {Panel} from "./Panel";
export class Board extends  React.Component{
  constructor(props){
    super();
  }

  getInitialState() {
    return {news: []};
  }

  componentWillMount(){
    $.ajax({
      url: "http://localhost:3003/json.txt",
      dataType: 'json',
      cache: false,
      success: (data) => {
        var arr=[];
        for (var key in data) {
          arr.push(data[key]);
          console.log(data[key]);
        }
        this.setState({news: arr});
      }
    });
  }
  render() {
    return (
        <div>
            {
                this.state.news.map((item,i)=> <Panel key="i"/>)
            }
        </div>
    );
  }
}

箭头功能处理绑定。 Simmilar到function(){}.bind(this)

答案 1 :(得分:2)

你正在进行异步的ajax调用......根据定义,它将继续执行代码而无需等待ajax的响应。

你可以通过在$ .ajax选项上设置async:false来转换同步。