如何使用React-Router基于URL /路径更新ReactJS组件

时间:2014-10-13 22:48:34

标签: reactjs react-router

使用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);

3 个答案:

答案 0 :(得分:9)

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

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

<Router history={browserHistory}>{routes}</Router>

答案 1 :(得分:6)

如果您正在使用react-router&gt;这已经更新。 V11.0。

您可以阅读the details here

TLDR:

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

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

答案 2 :(得分:3)

这个问题已经开放了一段时间,似乎应该有一个更直接的解决方案,但我会采取刺激并分享我们在申请中所做的事情。

我们正在使用Flux架构,它具有存储概念,可在组件状态更新时通知组件。在react-router中,他们有一个PathStore很适合这个模型,因为当URL更改时,它可以通知需要更新的组件。

我们在申请中使用的StoreListener可在此处公开获取:https://github.com/odysseyscience/react-flux-suppprt。我应该发布给NPM,但还没有。如果您认为这会有所帮助,我很快就会这样做。

以下是我们如何使用StoreListener来监听来自PathStore的{​​{1}}的更改,以及如何在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> ); } }); ,表示&#34;我关心路径存储的更改&#34;。每当此商店(或正在收听的任何商店)发生更改时,都会在您的组件上调用mixin,以便从getStateFromStores()上可用的商店中检索数据。如果/当数据发生变化时,会再次调用this.state,并重新阅读render(),并应用您的更改。

这正是我们应用某些&#34;活跃&#34;的模式。标题选项卡上的CSS类,或应用程序中依赖于当前URL的任何其他位置的CSS类。

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

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