首页 文章

React路由器应用程序 - 路由 Headers

提问于
浏览
8

我正在学习React并使用React-router . 应用程序我想在菜单栏中添加一个页面'title'来识别您当前所在的页面 .

我的路线:

<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调用返回的内容设置其 Headers .

我原本想过为每条路线添加回调,将 Headers 传递给它们的父类,而父类又可以将这些数据传递给NavigationMenu . 不幸的是,这不起作用:当您浏览页面时,重复调用的唯一函数是 render ,此处设置状态会引发 Invariant Violation 错误 .

我的问题

  • 管理 Headers 有更好的方法吗?

  • 跟踪 current 页面是否有任何替代方法,而不是依赖于路由渲染功能每次都将数据传递给回调(这看起来很脏)?

2 回答

  • 4

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

    Headers 组件:

    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>
        );
      }
    });
    

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

  • 8

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

    TitleActions

    import Reflux from 'reflux';
    
    export default Reflux.createActions([ 'update' ]);
    

    TitleStore

    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);
      }
    });
    

    NavigationMenu

    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>;
      }
    });
    

    MyComponent

    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 -> update action -> TitleStore -> NavigationMenu
    

相关问题