React路由器应用程序 - 路由标题

时间:2014-10-01 00:16:23

标签: reactjs react-router

我正在学习React并使用React-router。我建立的应用程序是一款移动风格的应用程序,其顶部导航菜单和下面的内容部分。当我浏览应用页面时,我想添加一个页面标题'到菜单栏以确定您当前所在的页面。

我的路线:

<Routes>
  <Route name='home' path='/' handler={HomePage}>
    <Route name='product-list' path='products/' handler={ProductList}/>
    <Route name='product-detail' path='product/:slug/' handler={ProductDetail} addHandlerKey={true}/>
  </Route>
</Routes>

HomePage.render:

<div className="container">
  <NavigationMenu />
  <div className="contents">
    {this.props.activeRouteHandler()}
  </div>
</div>

NavigationMenu.render:

<div className="navigationMenu">
  <div className="navigationMenuTitle>{this.props.title}</div>
</div>

我的问题

到HomePage的子路由需要根据Ajax调用返回的内容设置其标题。

我曾想过为每条路线添加回调,将标题传递回父类,而父类又可以将这些数据传递给NavigationMenu。遗憾的是,这不起作用:当您浏览页面时,重复调用的唯一函数是渲染,此处设置状态会引发Invariant Violation错误。

我的问题

  • 管理标题有更好的方法吗?
  • 跟踪当前页面是否有任何替代方法,而不是依赖路由渲染功能每次都将数据传递给回调(这看起来很脏)?

2 个答案:

答案 0 :(得分:8)

我能够使用React Flux模式解决这个问题并重新组织我的应用布局。

标题组件:

var Title = React.createClass({
  getInitialState: function() {
    return {
      title: Store.get()
    };
  },
  componentDidMount: function () {
    Store.addChangeListener(this._onChange);
  },
  componentWillUnmount: function() {
    Store.removeChangeListener(this._onChange);
  },
  _onChange: function() {
    this.setState({
      title: Store.get()
    });
  },
  render: function() {
    return (
      <span className="Title">{this.state.title}</span>
    );
  }
});

页面/内容组件遵循以下结构:

var Image = React.createClass({
  componentDidMount: function() {
    Action.update('Image - '+ this.props.params.service);
  },
  render: function() {
    var src = "http://place"+this.props.params.service+".com/g/400/400";
    return (
      <div className="Image">
        <img src={src}/>
      </div>
    );
  }
});

这允许组件加载,动态设置标题,并在应用程序良好且准备就绪时仅更新标题组件!漂亮!

答案 1 :(得分:4)

正如Jeff Fairley上面提到的那样,使用Reflux将有助于清理这一点(此代码使用ES6特性,因此需要运行它来进行转换):

<强> TitleActions

import Reflux from 'reflux';
import TitleActions from '../actions/title';

export default Reflux.createStore({
  listenables: TitleActions,

  getInitialState: function() {
    return 'My Cool New Project';
  },

  onUpdate(title) {
    this.trigger(title);
  }
});

<强> TitleStore

import React from 'react/addons';
import Reflux from 'reflux';
import TitleStore from '../stores/title';

export default React.createClass({
  mixins: [ Reflux.connect(TitleStore, 'title') ],

  render() {
    return <div className="navigationMenu">
      <div className="navigationMenuTitle>{this.state.title}</div>
    </div>;
  }
});

<强> NavigationMenu

import React from 'react/addons';
import Reflux from 'reflux';
import TitleActions from '../actions/title';

export default React.createClass({
  componentDidMount() {
    TitleActions.update('My Custom Title');
  },

  render() {
    return <div>My content.</div>;
  }
});

<强> MyComponent的

MyComponent -> update action -> TitleStore -> NavigationMenu

目标是保持平滑的单向数据流:

 while True:
    for update in bot.getUpdates(offset=LAST_UPDATE_ID, timeout=10):
        chat_id = update.message.chat.id
        update_id = update.update_id
        if update.message.text:
            #do things with the message \ start other functions and so on