377

react-routerv3 から v4に置き換えました。
しかし、のメンバー関数をプログラムでナビゲートする方法がわかりませんComponent。つまり、いくつかのデータを処理handleClick()した後にナビゲートしたい機能です。/path/some/where私はそれを次のように行っていました:

import { browserHistory } from 'react-router'
browserHistory.push('/path/some/where')

しかし、v4 にはそのようなインターフェイスが見つかりません。
v4 を使用してナビゲートするにはどうすればよいですか?

4

17 に答える 17

440

ブラウザ環境をターゲットにしている場合はreact-router-dom、 の代わりに packageを使用する必要がありますreact-routerreactコア ( ) とプラットフォーム固有のコード ( react-dom、 )を分離するために、React と同じアプローチに従っていreact-nativeますが、2 つの個別のパッケージをインストールする必要がないという微妙な違いがあるため、環境パッケージにはすべてが含まれています。あなたが必要です。次のようにプロジェクトに追加できます。

yarn add react-router-dom

また

npm i react-router-dom

最初に行う必要があるのは<BrowserRouter>、アプリケーションの最上位の親コンポーネントとして を提供することです。<BrowserRouter>は HTML5 historyAPI を使用して管理するため、自分でインスタンス化して props としてコンポーネントに渡すことについて心配する<BrowserRouter>必要はありません (以前のバージョンで必要でした)。

V4 では、プログラムでナビゲートするには、オブジェクトにアクセスする必要があります。このオブジェクトは、アプリケーションの最上位の親としてプロバイダーコンポーネントを持っている限り、historyReact を介して利用できます。ライブラリは、それ自体がプロパティとして含まれているオブジェクトをコンテキストを通じて公開します。インターフェイスには、、、 などのいくつかのナビゲーション方法が用意されています。プロパティとメソッドの全リストはこちらで確認できます。context<BrowserRouter> routerhistoryhistorypushreplacegoBack

Redux/Mobx ユーザーへの重要な注意事項

アプリケーションで状態管理ライブラリとして redux または mobx を使用している場合、位置を認識する必要があるにもかかわらず、URL 更新をトリガーした後に再レンダリングされないコンポーネントで問題が発生する可能性があります。

これは、コンテキスト モデルを使用してコンポーネントにreact-router渡すために発生しています。location

connect とobserver はどちらも、 shouldComponentUpdate メソッドが現在の props と次の props の浅い比較を行うコンポーネントを作成します。これらのコンポーネントは、少なくとも 1 つのプロップが変更された場合にのみ再レンダリングされます。これは、場所が変更されたときに確実に更新されるようにするには、場所が変更されたときに変更される小道具を与える必要があることを意味します。

これを解決するための 2 つのアプローチは次のとおりです。

  • 接続されたコンポーネントを pathless でラップします<Route />。現在のオブジェクトは、レンダリングするコンポーネントに渡すlocationprops の 1 つです。<Route>
  • 接続されたコンポーネントをwithRouter高次コンポーネントでラップします。実際には同じ効果がありlocation、小道具として注入されます

それはさておき、プログラムでナビゲートする方法は 4 つあります。

1.-<Route>コンポーネントの使用

宣言的なスタイルを促進します。v4 より前は、<Route />コンポーネントはコンポーネント階層の最上位に配置されていたため、事前にルート構造を考慮する必要がありました。ただし、ツリー内の任意の場所<Route>にコンポーネントを配置できるようになったため、URL に応じて条件付きレンダリングをより細かく制御できるようになりました。を挿入し、小道具としてコンポーネントに挿入します。ナビゲーション メソッド ( 、、... など) は、オブジェクトのプロパティとして使用できます。RoutematchlocationhistorypushreplacegoBackhistory

またはprops のRouteいずれかを使用して、 でcomponent何かをレンダリングする方法は 3 つありますが、同じ で複数を使用しないでください。選択はユース ケースによって異なりますが、基本的に最初の 2 つのオプションは、URL の場所と一致する場合にのみコンポーネントをレンダリングしますが、パスが場所と一致するかどうかにかかわらず、コンポーネントはレンダリングされます (URL に基づいて UI を調整する場合に役立ちます)。マッチング)。renderchildrenRoutepathchildren

コンポーネントのレンダリング出力をカスタマイズする場合は、コンポーネントを関数でラップし、 オプションを使用して、 と以外のrender必要なその他の小道具をコンポーネントに渡す必要があります。説明する例:matchlocationhistory

import { BrowserRouter as Router } from 'react-router-dom'

const ButtonToNavigate = ({ title, history }) => (
  <button
    type="button"
    onClick={() => history.push('/my-new-location')}
  >
    {title}
  </button>
);

const SomeComponent = () => (
  <Route path="/" render={(props) => <ButtonToNavigate {...props} title="Navigate elsewhere" />} />
)    

const App = () => (
  <Router>
    <SomeComponent /> // Notice how in v4 we can have any other component interleaved
    <AnotherComponent />
  </Router>
);

2.- HoC のwithRouter使用

この高次コンポーネントは、 と同じ props を注入しRouteます。ただし、ファイルごとに 1 つの HoC しか持てないという制限があります。

import { withRouter } from 'react-router-dom'

const ButtonToNavigate = ({ history }) => (
  <button
    type="button"
    onClick={() => history.push('/my-new-location')}
  >
    Navigate
  </button>
);


ButtonToNavigate.propTypes = {
  history: React.PropTypes.shape({
    push: React.PropTypes.func.isRequired,
  }),
};

export default withRouter(ButtonToNavigate);

3.-Redirectコンポーネントの使用

をレンダリングする<Redirect>と、新しい場所に移動します。ただし、デフォルトでは、サーバー側のリダイレクト (HTTP 3xx) のように、現在の場所が新しい場所に置き換えられることに注意してください。新しい場所はtoprop によって提供され、文字列 (リダイレクト先の URL) またはlocationオブジェクトにすることができます。代わりに履歴に新しいエントリをプッシュしたい場合は、 pushprop も渡し、それをtrue

<Redirect to="/your-new-location" push />

4.-routerコンテキストから手動でアクセスする

コンテキストはまだ実験的な API であり、React の将来のリリースで壊れたり変更されたりする可能性があるため、少しお勧めできません。

const ButtonToNavigate = (props, context) => (
  <button
    type="button"
    onClick={() => context.router.history.push('/my-new-location')}
  >
    Navigate to a new location
  </button>
);

ButtonToNavigate.contextTypes = {
  router: React.PropTypes.shape({
    history: React.PropTypes.object.isRequired,
  }),
};

言うまでもなく、ブラウザ以外のエコシステム向けの他の Router コンポーネントもあります。たとえば、ナビゲーション スタックをメモリに<NativeRouter>複製し、React Native プラットフォームをターゲットにして、パッケージから入手できます。react-router-native

詳細については、公式ドキュメントを参照してください。ライブラリの共著者の 1 人が作成したビデオもあり、 react-router v4 の非常にクールな紹介を提供し、主要な変更点のいくつかを強調しています。

于 2017-02-08T21:51:29.253 に答える
9

ステップ 1: 一番上にインポートするものは 1 つだけです。

import {Route} from 'react-router-dom';

ステップ 2: ルートで、履歴を渡します。

<Route
  exact
  path='/posts/add'
  render={({history}) => (
    <PostAdd history={history} />
  )}
/>

ステップ 3: history は次のコンポーネントの props の一部として受け入れられるため、次のことが簡単にできます。

this.props.history.push('/');

それは簡単で、本当に強力でした。

于 2017-09-29T15:11:03.827 に答える