4

現在、ルート アプリケーション レベルでのreact-router リンク ナビゲーションshouldComponentUpdate()の正しい組み合わせの実装について疑問があります。

つまり、ヘッダー、フッター、サイドバーなどを含むグローバル コンポーネントを含むApp.jsxというルート コンポーネントがあり、この同じコンポーネントには、システム内の新しい登録を取得し、新しいユーザーが登録したときに状態を更新するajax long-pollがあります。 .

更新を持たない ajax 応答でコンポーネント(したがってすべての子)に再レンダリングをプッシュしたくないので、素敵なshouldComponentUpdate()メソッドを使用することにしました。

だから、私はこのようなものを思いつきました-私はlo-dashを利用していることに注意してください:

shouldComponentUpdate (/*prevProps*/, prevState) {
  return !_.isEqual(this.state,prevState);
}

これにより、コンポーネントは最新の登録に関する無関係な応答を正しく無視します。

ここで、ルーティングを行う必要があるときに問題が発生します。前に明確にするために、これはrender()の一種の構造です:

注: _routerTransitionKey は単なるヘルパーです。内部ビューの状態をナビゲートしているときにトランジションを行う必要がなく、正常に動作しています。

<Grid key='app' id="wrapper" className="no-padding">
  <Header user={this.state.user} allRegistrations={this.state.allRegistrations}/>
  <section id="page-wrapper">
    <NotificationArea key='internalNotification' />
    <RouteHandler key={_routerTransitionKey} user={this.state.user} allRegistrations={this.state.allRegistrations}/>
  </section>
</Grid>

このグローバル コンポーネント内に RouteHandler があるため、アプリケーションの状態自体が変更されなかったため、ルートの変更が完全に無視されるという問題があります。これにより、コンポーネントはナビゲーション時にrender()をトリガーせず、したがってRouteHandler を更新しません。

私が必要としたのは次のようなものです:

 shouldComponentUpdate (/*prevProps*/, prevState) {
   return !_.isEqual(this.state,prevState) || ROUTE_CHANGED ;
 }

私の質問は、この問題に対する巧妙なアプローチを知っている人はいますか? 現在持っているこのアプリコンポーネントに到達する前に、ルートを処理するためにさらに別のラッピングコンポーネントを作成する必要がないようにしようとしています...

4

1 に答える 1

0

したがって、@WayneC からのヒントの後、react-router がプロップを反応コンポーネントのプロップに直接注入しなくても、そのアプローチに触発された方法が考えられます。

this.propsではなく、this.context.router.getCurrentPath()を使用してわずかな変更を加えることで、私が望んでいたことを達成しました。

したがって、ソリューションは次のようになります。

shouldComponentUpdate (/*nextProps*/, nextState) {
  return !_.isEqual(this.state,nextState) || this.context.router.getCurrentPath() !== _routerTransitionKey;
}

わかりやすくするために、私の _routerTransitionKey は、ほとんど次のようなインポートされた Util から値を取得します。

var Utils = {
  Router: {
    TransitionKey: {
      get: function(){
        return Router.HistoryLocation.getCurrentPath();
      }
    }
  }
}

_routerTransitionKey = Utils.Router.TransitionKey.get();

これは上位レベルでスコープされており、後で比較するために追跡できるように、render()_routerTransitionKeyごとに変更します。

以上です。

于 2015-05-06T14:34:08.307 に答える