web-dev-qa-db-ja.com

反応ルーターv4でルート変更を検出する方法?

変数をtrueに変更できるように、ルートの変更が発生したかどうかを検出する必要があります。

私はこれらの質問に目を通しました:
1。 https://github.com/ReactTraining/react-router/issues/3554
2。 react router v4のルート変更をリッスンする方法?
3。 react-routerを使用したルート変更の検出

それらのどれも私のために働いていません。ルートの変更が発生したときに関数を呼び出す明確な方法はありますか。

8
HunterLiu

1つの方法は、withRouter高次コンポーネントを使用することです。

ライブデモ(ハイパーリンクをクリックしてルートを変更し、表示されたコンソールで結果を表示します)

WithRouter高次コンポーネントを介して、履歴オブジェクトのプロパティと最も近いものにアクセスできます。 withRouterは、レンダリングされるたびに、ラップされたコンポーネントに更新された一致、場所、および履歴の小道具を渡します。

https://github.com/ReactTraining/react-router/blob/master/packages/react-router/docs/api/withRouter.md

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

class App extends Component {
    componentDidUpdate(prevProps) {
        if (this.props.location.pathname !== prevProps.location.pathname) {
            console.log('Route change!');
        }
    }
    render() {
        return (
            <div className="App">
                ...routes
            </div>
        );
    }
}

export default withRouter(props => <App {...props}/>);

URLパラメーターを使用する別の例:

プロファイルルートを/profile/20から/profile/32に変更した場合

そして、ルートは/profile/:userIdとして定義されました

componentDidUpdate(prevProps) {
    if (this.props.match.params.userId !== prevProps.match.params.userId) {
        console.log('Route change!');
    }
}
18
wdm

Reactフックを使用すると、次のように簡単になります。

useEffect(() => {
    const { pathname } = location;
    console.log('New path:', pathname);
}, [location.pathname]);

2番目の配列引数にlocation.pathnameを渡すことは、location.pathnameが変更された場合にのみ再実行するようにuseEffectに言っていることを意味します。

コードソースを使用したライブ例: https://codesandbox.io/s/detect-route-path-changes-with-react-hooks-dt16i

6
parse

React Router v5は、フックのおかげでルートの変更を自動的に検出するようになりました。 チームの例 の背後にあります:

import { Switch, useLocation } from 'react-router'

function usePageViews() {
  let location = useLocation()

  useEffect(
    () => {
      ga.send(['pageview', location.pathname])
    },
    [location]
  )
}

function App() {
  usePageViews()
  return <Switch>{/* your routes here */}</Switch>
}

この例では、URLが変更されるたびに「ページビュー」をGoogleアナリティクス(ga)に送信します。

2

コンポーネントが<Route>componentプロパティとして指定されている場合、React=ルーター4(RR4)はいくつかの追加プロパティを渡します:matchlocationおよびhistory

次に、componentDidUpdateライフサイクルメソッドを使用して、更新前と更新後のlocationオブジェクトを比較する必要があります(ESオブジェクト比較ルールを忘れないでください)。ロケーションオブジェクトは不変であるため、一致しません。 uが同じ場所に移動しても。

  componentDidUpdate(newProps) {
    if (this.props.location !== newProps.location) {
      this.handleNavigation();
    }
  }

ルートのwithRouterプロパティとして指定されていない任意のコンポーネント内でこれらのプロパティにアクセスする必要がある場合は、componentを使用する必要があります。アプリは必要なすべてのAPIを提供するため、必ず<BrowserRouter>でラップしてください。そうしないと、これらのメソッドは<BrowserRouter>に含まれるコンポーネントでのみ機能します。

ユーザーがブラウザの専用インターフェイスの代わりにナビゲーションボタンを使用してページをリロードすることを決定する場合があります。しかし、このような比較:

this.props.location.pathname !== prevProps.location.pathname

不可能になります。

1
user10917078

Reactはコンポーネントベースのアーキテクチャを使用します。それでは、なぜこの規則に従わないのでしょうか?

[〜#〜] demo [〜#〜] が表示されます。

各ページはHOCでラップする必要があります。これにより、ページの変更が自動的に検出されます。

ホーム

import React from "react";
import { NavLink } from "react-router-dom";
import withBase from "./withBase";

const Home = () => (
  <div>
    <p>Welcome Home!!!</p>
    <NavLink to="/login">Go to login page</NavLink>
  </div>
);

export default withBase(Home);

with Base HOC

import React from "react";

export default WrappedComponent =>
  class extends React.Component {
    componentDidMount() {
      this.props.handleChangePage();
    }

    render() {
      return <WrappedComponent />;
    }
  };
0
Ukasha

アプリケーション状態の履歴オブジェクトの長さを追跡するのはどうですか? react-routerによって提供される履歴オブジェクトは、新しいルートがトラバースされるたびに長さが増加します。下の画像をご覧ください。

enter image description here

ComponentDidMountおよびComponentWillUnMountチェック: enter image description here