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

IT技术 reactjs react-router
2021-05-13 14:42:42

使用 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个回答

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

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

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

如果您使用的是 react-router > v11.0,这已经更新。

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

域名注册地址:

 // 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

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

我们正在使用 Flux 架构,它具有 Stores 的概念,当组件的状态更新时通知组件。在 中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 module,因此可能存在一些关于环境的假设,这些假设可能/可能不适合您。

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