从异步服务器端数据调用中渲染ReactJS

时间:2016-09-12 02:07:52

标签: javascript asynchronous reactjs

我对ReactJS比较陌生。我真的很喜欢反应渲染数据的方式。但是,我发现当我开始使用异步调用来检索和呈现服务器端数据时,有一些奇怪的行为。我有一个组件调用子组件并呈现服务器端数据。

服务器端调用是异步调用。我的代码类似于:

class myComponent extends component {

    constructor(props) {
        super(props);
        this.componentDidMount = this.componentDidMount.bind(this);
        this.state = {myVariable: []};

    }
    this.componentDidMount() {
        fetch() => { server side async call to retrieve data
        this.setState({myVariable: serverData});
    }

    render() {
        <div className="myClass">
            <div className="renderMyBox">
                <div> {this.state.myVariable} </div>
            </div>
        </div>
    }
}

我面临的问题是。前两个div立即在服务器上呈现,然后几乎有1秒的延迟,其中有一个空div,然后由于异步调用而设置状态。然后状态的改变触发重新渲染。

在异步调用成功并设置状态之前,有什么方法可以强制渲染不发生?有解决方法吗?

2 个答案:

答案 0 :(得分:2)

正如elmaister指出的那样,在有数据之前你什么都不会返回。这可以通过观察isReady变量来处理:

class myComponent extends component {

  constructor(props) {
    super(props);
    this.componentDidMount = this.componentDidMount.bind(this);
    this.state = { myVariable: [], isReady: false };
  }

  this.componentDidMount() {
    fetch() => { server side async call to retrieve data
      this.setState({
        myVariable: serverData,
        isReady: true
      });
    }

  render() {
    if (this.state.isReady) {
      return <div className="myClass">
        <div className="renderMyBox">
           <div> {this.state.myVariable} </div>
        </div>
      </div>
    }
  }

}

答案 1 :(得分:0)

您可以在fetch中使用setState,或使用jquery.ajax({ async: false })

function getData(url) {
    var response = null;

    window.jQuery.ajax(
        {
        url: url,
        dataType: 'json',
        async: false,
        success: function(data) {
            response = data;
        }.bind(this),
    });

    return response;
}

如果您在请求之前想要无渲染,可以添加:

render() {
    if(this.state.myVariable.length == 0){
        return null;
    }
   ...your code
}

通常的方法是设置loading变量:

constructor(){
    this.state = {
        data: defaultData,
        loading: true
    };
}
componentDidMount(){
    request.done(data){
       this.setState({
           data: data,
           loading: false,
       })
    }
}
render() {
    if(this.state.loading){
       //return loading style
    }
   ...your code
}