如何使组件/应用程序等待ajax调用

时间:2015-10-26 21:20:48

标签: reactjs

我试图找到让我的应用程序和组件依赖于我正在进行的单个ajax调用的最佳方法。我的应用程序通过第三方进行身份验证,并向用户显示任何有意义的信息,我必须使用其登录信息,然后调用其他服务以获取有关它们的详细信息。我从几个例子中得出,到目前为止还有这个

//auth.js
module.exports = {
  login(cb) {
    if (this.user) {
      if (cb) cb(true)
      this.onChange(true)
      return;
    }
    //if we don't have info about the user we call the other service here
    request((res) => {
      if (res) {
        this.user = res
        if (cb) cb(true)
        this.onChange(true)
      } else {
        if (cb) cb(false)
        this.onChange(false)
      }
    })
  },

  getUser() {
    return this.user
  },

  logout(cb) {
    delete this.user
    if (cb) cb()
    this.onChange(false)
  },

  loggedIn() {
    return !!this.user
  },

  onChange() {}
}

然后在我的组件中,我在整个地方这样做,这看起来并不像一个伟大的模式。

import React from 'react';
import ReactDOM from 'react-dom';
import auth from './auth'

export class ProductList extends React.Component{

  constructor(props) {
      super(props);
      //subscribe to on change event from the auth class
      auth.onChange = this.updateAuth.bind(this)
      this.state = {results: []};
  }

  componentWillMount() {
    //call login. if already logged in this method just returns the current user
    auth.login();
  }

  getProducts() {
    if(this.state.loggedIn) {
      $.get(config.server.url + "/api/User/" + auth.getUser().Id + "/Products", function(result) {
        this.setState({
          results: result.data.products
        });
      }.bind(this));
    }
  }

  updateAuth(loggedIn) {
    this.setState({
      loggedIn: loggedIn
    });
    this.getProducts()
  }

  componentDidMount() {
    this.getProducts()
  }

  render() {
    return (
      <table>
        <tbody>
            {this.state.results.map(function(result) {
               return <ProductItem key={result.Id} data={result}/>;
            })}
        </tbody>
      </table>
    )
  }
};

ReactDOM.render(
  (<ProductList/>),
  document.getElementById('react-forms')
);

所以我基本上只是在我拥有的每个反应组件中连接一个事件处理程序,并在整个地方检查相同的属性,它看起来很脆弱。我想我正在寻找一种方法告诉我&#39; App&#39;在我的组件有效之前,我正在等待事情发生。

1 个答案:

答案 0 :(得分:0)

我建议您遵循反应教程(https://facebook.github.io/react/docs/tutorial.html#fetching-from-the-server)中概述的结构。 ajax调用是使用jquery ajax函数从顶级组件CommentBox进行的,然后通过props传递给其他组件CommentListCommentForm。下面的代码直接来自教程。由于您使用的是es6,因此语法略有不同,但概念保持不变。

var CommentBox = React.createClass({
  loadCommentsFromServer: function() {
    $.ajax({
      url: this.props.url,
      dataType: 'json',
      cache: false,
      success: function(data) {
        this.setState({data: data});
      }.bind(this),
      error: function(xhr, status, err) {
        console.error(this.props.url, status, err.toString());
      }.bind(this)
    });
  },
  getInitialState: function() {
    return {data: []};
  },
  componentDidMount: function() {
    this.loadCommentsFromServer();
    setInterval(this.loadCommentsFromServer, this.props.pollInterval);
  },
  render: function() {
    return (
      <div className="commentBox">
        <h1>Comments</h1>
        <CommentList data={this.state.data} />
        <CommentForm />
      </div>
    );
  }
});