在ReactRouter的willTransitionTo和willTransitionFrom中访问组件上下文

时间:2015-06-18 10:13:21

标签: reactjs flux react-router

我需要在每次呈现页面时从服务器获取数据。

通常这个(ajax)请求应该在componentDidMount内执行,但是对于ReactRouter,当网址发生变化时,不会触发componentDidMount

这是我到目前为止的尝试:

// App.js
var App = React.createClass({
  render: function() {
    return (
      <RouteHandler />
    );
  }

  var routes = (
    <Route handler={App} path="/" >
      ...
      <Route handler={PageA} name="PageA" path="/pagea" />
      ...
    </Route>
  );

  Router.run(routes, Router.HashLocation, function(Handler) {
    React.render(<Handler/>, document.body);
  });
});

// PageA.js
var PageA = React.createClass({
  statics: {
    willTransitionTo: function (transition, params, query, callback) {
      console.log("willTransitionTo PageA");
      this.handleGet(callback);
    }

    , willTransitionFrom: function (transition, component) {
      console.log("willTransitionFrom PageA");
    }
  }

  , handleGet(callback) { ... }

  ...
}

我想拦截一个事件&#39;页面会出现&#39;并且willTransitionTo(和willTransitionFrom)似乎按预期完成了工作。但是,问题是我无法在该方法中访问PageA.handleGet。如果您能指导我完成这项任务,我将不胜感激,因为我可能会误解使用路由器的一些重要概念。

P.S。我还没有使用Flux。

1 个答案:

答案 0 :(得分:0)

我在here找到了一种解决方法,其中使用包装器将获取的数据作为props传递给目标组件(PageA)。我不得不在目标组件的componentDidMount中管理ajax请求,而是必须在包装器组件的componentDidMount中进行。这样,如果有许多页面处理预加载请求,App.js会变得非常大。

// App.js
var PageAWrapper = React.createClass({

  getInitialState: function() {
    return {
      data: []
    };
  }

  , handleGet: function() {
      var promise = $.ajax({...});
      promise.done(function(data) {
        this.setState({data: data});
      }.bind(this));
  }  

  , componentDidMount: function() {
    this.handleGet();
  }

  , render: function () {
    return (
      <PageA data={this.state.data} />
    );
  }
});

...
var routes = (
  <Route handler={App} path="/" >
    ...
    <Route handler={PageAWrapper} name="PageA" path="/pagea" />
    ...
  </Route>
);

修改

因为data内的PageA是可变的,但我被迫将其作为props传递。因此,我还必须稍微修改PageA

var PageA = React.createClass({
  getInitialState: function() {
    return {
      data: []
    };
  }

  , componentWillReceiveProps: function(nextProps) {
    this.setState({data: nextProps.data})
  }

  , render: function() {
    ... use this.state.data to render ...
  }
});