8

我正在学习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错误。

我的问题

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

2 回答 2

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

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

于 2014-10-02T22:48:30.743 回答
4

正如上面 Jeff Fairley 所建议的,使用 Reflux 将有助于清理这个问题(此代码使用 ES6 功能,因此需要一个转译器来运行它):

标题动作

import Reflux from 'reflux';

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

标题商店

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
于 2015-11-11T16:32:33.793 回答