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 に渡すことを考えていました。残念ながら、これは機能しません。ページをナビゲートするとき、繰り返し呼び出される唯一の関数はrenderであり、ここで状態を設定すると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>;
  }
});

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