【问题标题】:React router app - Route titleReact 路由器应用程序 - 路由标题
【发布时间】:2014-11-25 18:08:13
【问题描述】:

我正在学习 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。不幸的是,这不起作用:当您浏览页面时,唯一重复调用的函数是 render 并且在此处设置状态会引发 Invariant Violation 错误。

我的问题

  • 有没有更好的方法来管理标题?
  • 除了依靠路由渲染函数每次都将数据传递给回调(这看起来很脏)之外,还有其他方法可以跟踪当前页面吗?

【问题讨论】:

    标签: reactjs react-router


    【解决方案1】:

    我能够使用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>
        );
      }
    });
    

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

    【讨论】:

    • 还可以查看Reflux 以减少样板代码
    【解决方案2】:

    正如上面 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);
      }
    });
    

    导航菜单

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

    我的组件

    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
    

    【讨论】:

      猜你喜欢
      • 2021-05-12
      • 1970-01-01
      • 2015-12-08
      • 1970-01-01
      • 2020-11-21
      • 1970-01-01
      • 1970-01-01
      • 2018-09-15
      • 1970-01-01
      相关资源
      最近更新 更多