21

使用 React-Router 时如何根据 URL / 路径更新 ReactJS 组件?

下面的代码有效,但这是正确的方法吗?似乎有很多代码可以进行简单的更新。我希望路由器中有一个有状态的 API 调用来自动处理这种情况。

var MyHomeView = React.createClass({
   componentDidMount: function() {
        this.props.updateHeader(); 
   },

   render: function() {
      return (
         <div>
            <h2>Home</h2>
         </div>
      );
  } 
}); 


var MyAboutView = React.createClass({
   componentDidMount: function() {
        this.props.updateHeader(); 
   },

  render: function() {
    return (
      <div className="my-page-text">
        <h2>About</h2>
      </div>
    );
  }
});


var MyHeader = React.createClass({
  mixins: [ CurrentPath ],

  getInitialState: function() {
    return {
       myPath: "about",
       classes: "ion-ios7-information"
    };
  },   

   updateHeader: function() {    
      // Classnames refer to www.ionicons.com
     if (this.getCurrentPath() === "/") {
        this.setState( {myPath: "about" } );
        this.setState( {classes: "ion-ios7-information" } );
     } else {
        this.setState( {myPath: "/" } );
        this.setState( {classes: "ion-ios7-rewind" } );
     }      
   }, 

  render: function() {
    return (
       <Link to={this.state.myPath}>
          <i className={this.state.classes} />
       </Link>
    );
  }
});


var App = React.createClass({
   updateHeader: function() {
      this.refs.header.updateHeader();
   },

   render: function() {
      return (
         <div>
            <MyHeader ref="header" />

         <this.props.activeRouteHandler updateHeader={this.updateHeader} />
         </div>
      );
  } 
}); 


React.renderComponent((
  <Routes> 
    <Route path="/" handler={App}>
      <DefaultRoute handler={MyHomeView} />
      <Route name="about" handler={MyAboutView} />
    </Route>
  </Routes>
), document.body);
4

3 回答 3

9

在 react-router 2.0.0 中,您可以使用 hashHistory 或browserHistory

browserHistory.listen(function(ev) {
  console.log('listen', ev.pathname);
});

<Router history={browserHistory}>{routes}</Router>
于 2016-02-24T23:30:03.783 回答
6

如果您正在使用 react-router > v11.0,这已更新。

您可以在此处阅读详细信息

TLDR:

 // v0.11.x
 var Something = React.createClass({
   mixins: [ Router.State ],
   render: function () {
      var path = this.getPath();
   }
 });

对于完整的StateAPI:https ://github.com/rackt/react-router/blob/master/doc/04%20Mixins/State.md

于 2015-02-05T21:16:59.750 回答
3

这个问题已经开放了一段时间,似乎应该有一个更直接的解决方案,但我会尝试并分享我们在应用程序中所做的事情。

我们使用的是 Flux 架构,它具有 Store 的概念,当组件的状态更新时通知组件。在react-router中,他们有一个非常PathStore适合这个模型,因为当 URL 发生变化时,它可以通知关心和需要更新的组件。

StoreListener我们在应用程序中使用的内容可在此处公开获得:https ://github.com/odysseyscience/react-flux-suppprt。我应该已经发布到 NPM,但还没有。如果您认为这会有所帮助,我会尽快这样做。

以下是我们如何使用 ourStoreListener来监听PathStorefrom的变化react-router,以及您将如何在您的 中使用它MyHeader

var StoreListener = require('path/to/StoreListener');
var PathStore = require ('react-router/modules/stores/PathStore');

var MyHeader = React.createClass({
  mixins: [
    StoreListener(PathStore)
  ],

  getStateFromStores: function() {
    return {
        path: PathStore.getCurrentPath()
    };
  },

  render: function() {
    var path = this.state.path;
    var myPath;
    var classes;

    if (this.state.path === "/") {
      myPath = 'about';
      classes = 'ion-ios7-information';
    } else {
      myPath = '/';
      classes = 'ion-ios7-rewind';
    } 

    return (
      <Link to={myPath}>
        <i className={classes} />
      </Link>
    );
  }
});

这以mixin“我关心 PathStore 的更改”开头。每当此存储(或任何正在侦听的存储)发生更改时,getStateFromStores()都会在您的组件上调用,以便从存储中检索您希望在 上可用的数据this.state。如果/当该数据更改时,render()将再次调用,然后您重新读取this.state并应用您的更改。

这正是我们在标题选项卡或应用程序中依赖于当前 URL 的任何其他位置应用某些“活动”CSS 类的模式。

请注意,我们使用webpack来捆绑我们的 CommonJS 模块,因此可能会有一些关于环境的假设可能/可能不适合您。

一个月前我第一次看到这个问题时没有回答,因为我认为有更好的方法,但也许我们的解决方案可以帮助其他人解决同样的问题。

于 2014-11-27T07:43:19.463 回答