ReactルーターはURLを変更しますが、表示しません


87

ルーティングに反応してビューを変更するのに問題があります。ユーザーのリストのみを表示したいので、各ユーザーをクリックすると詳細ページに移動する必要があります。ルーターは次のとおりです。

import React from "react";
import ReactDOM from "react-dom";
import { BrowserRouter } from 'react-router-dom';
import Users from "./components/Users";
import { Router, Route } from "react-router";
import Details from "./components/Details";

ReactDOM.render((
  <BrowserRouter>
    <div>
        <Route path="/" component={Users} />
        <Route path="/details" component={Details} />
    </div>
  </BrowserRouter>
), document.getElementById('app'))

URL / detailsを使用すると、ブラウザはそのURLに移動しますが、ビューは変更されません。他のルートは404をスローするため、ルートを認識しているように見えますが、更新されていません。


2つのエラーが発生します。1つはメインのreactパッケージのproptypesの使用が非推奨であることを示しています。React.createClassを使用する2つの記述は非推奨です。コードはルーティングを使用せずに機能するため、これは無関係だと思いました。
MARyan87 2017

コンポーネントは正しく取り付けられていますか?
ジェレミージョン

回答:


74

exactindexRouteの属性を指定する必要があります。そうしないと、/detailsルートであっても、と一致し/ます。また、からインポートRouteしてみてくださいreact-router-dom

import React from "react";
import ReactDOM from "react-dom";
import { BrowserRouter, Route } from 'react-router-dom';
import Users from "./components/Users";

import Details from "./components/Details";

ReactDOM.render((
  <BrowserRouter>
    <div>
        <Route exact path="/" component={Users} />
        <Route path="/details" component={Details} />
    </div>
  </BrowserRouter>
), document.getElementById('app'))

更新:

あなたがする必要があるもう一つのことはあなたのコンポーネントUsersをでアタッチすることですwithRouterwithRouterコンポーネントが、を受信して​​いない場合にのみ使用する必要がありますRouter props

あなたのコンポーネントがある場合、これは場合によっては起こるかもしれルータによってレンダリングコンポーネントのネストされた子、あなたがそれにルータの小道具を合格していないか、コンポーネントは、すべてのルータにリンクされていないとは別個の構成要素としてレンダリングされるときルート。

Users.jsに追加

import {withRouter} from 'react-router';

.........
export default withRouter(Users)

ドキュメント


proptypesの警告はnpm install -S 'prop-types'、React.PropsTypesをインストールしてPropTypesに置き換えることで削除できます。また、他のパッケージがまだReact.PropTypesとReact.createClassを使用している可能性があるため、package.jsonを更新して、最新のパッケージを利用します
Shubham Khatri

また、URLが変更されたときにページをリロードして、ロードされるかどうかを確認しようとしていますか
Shubham Khatri 2017

ページをリロードしてみましたが、ビューは変わりません。URLが/#/ detailsであっても、ユーザービューに読み込まれます
MARyan87 2017

1
Route代わりに「react-router-dom」からインポートして更新された回答を試すことができますかreact-router
Shubham Khatri 2017

まだ解決されていない場合は、ユーザーコンポーネントをでバインドしますwithRouter。これは、以前に同じ問題を解決するのに役立ちました。お知らせ下さい。私もコードを更新しました。
Shubham Khatri 2017

27

コンポーネントをwithRouterでラップするだけです

<Route exact path="/mypath" component={withRouter(MyComponent)} />

App.jsファイルのサンプルは次のとおりです。

...
import { BrowserRouter as Router, Route, Switch, withRouter } from "react-router-dom";
import Home from "./pages/Home";
import Profile from "./pages/Profile";

class App extends Component {
  render() {
    return (
      <Router>
        <Switch>
          <Route exact path="/" component={withRouter(Home)} />
          <Route exact path="/profile" component={withRouter(Profile)} />
        </Switch>
      </Router>
    );
  }
}

export default App;

追加

反応ルーターを使用している場合、URLが変更されるたびにcomponentWillReceivePropsが呼び出されます。

componentWillReceiveProps(nextProps) {
    var currentProductId = nextProps.match.params.productId;
    var nextProductId = nextProps.match.params.productId; // from the new url
    ...
}

注意

または、エクスポートする前にコンポーネントをwithRouterでラップすることもできますが、その場合は、他のいくつかのことを確認する必要があります。私は通常、このステップをスキップします。

export default withRouter(Profile)

3
<Route Accurate Path = "/ mypath" component = {withRouter(MyComponent)} />は私のために働いた
Santosh Kumar

15

同じ問題が発生し、ネストされたルーターが原因であることがわかりました。ネストされたルーターを削除し、コンポーネント固有のルートをスイッチコンポーネント内に配置すると、withRouterを使用したり、追加の変更を加えたりすることなく、問題が解決しました。

<Router> // <--Remove nested Router
    <Switch>
      <Route exact path="/workflows" component={ViewWorkflows} />
      <Route path="/workflows/new" component={NewWorkflow} />
    </Switch>
</Router>

Yusufbekは同様の問題について説明しています。コンポーネントに関連するルートをビューレベルで保存する方が、すべてを1つのメインルーターに保存するよりもはるかにクリーンだと思います。本番アプリでは、問題を簡単に読み取ってデバッグするには、ルートが多すぎます。


14

同じ問題に直面しましたが、修正しました。最後にホームページを配置しました。わたしにはできる。以下のように。

    import React from "react";
    import ReactDOM from "react-dom";
    import { BrowserRouter } from 'react-router-dom';
    import Users from "./components/Users";
    import { Router, Route } from "react-router";
    import Details from "./components/Details";

    ReactDOM.render((
      <BrowserRouter>
        <div>
            <Route path="/details" component={Details} />
            <Route path="/" component={Users} />
        </div>
      </BrowserRouter>
    ), document.getElementById('app'))


5
exactプロパティを使用すると、これも解決されます。
イシャウッド

8

Reduxを使用しているときに、アドレスバーでURLが更新されていても、アプリがそれぞれのコンポーネントを読み込まないという同様の問題が発生しました。withRouterをエクスポートに追加することで解決できました:

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

export default withRouter(connect(mapStateToProps)(MyComponentName))

7

同様の問題がありましたが、構造が異なります。すべてのルートを処理するルーターを1つ追加し、Switchコンポーネントを使用してビューを切り替えました。しかし実際にはそうではありませんでした。URLのみが変更され、表示されません。この理由は、ルーターコンポーネントの外部にあるサイドバーコンポーネントの内部で使用されるリンクコンポーネントでした。(はい、「withRouter」を使用してSideBarをエクスポートしましたが、機能しません)。したがって、解決策は、すべてのリンクコンポーネントを保持するSideBarコンポーネントをルーターに移動することでした。

問題は私のリンカーにあります、彼らは私のルーターの外にあります

<div className="_wrapper">
  <SideBar /> // Holds my all linkers
  <Router>
     <Switch>
       <Route path="/" component={Home} />
       <Route path="/users" component={Users} />
     </Switch>
  </Router>
 </div>

解決策は、リンカーをルーターに移動することでした

<div className="_wrapper">
  <Router>
     <SideBar /> // Holds my all linkers
     <Switch>
       <Route path="/" component={Home} />
       <Route path="/users" component={Users} />
     </Switch>
  </Router>
</div>

3
自分を助けて私の一日を作りました。私は2つの別々のルーターでそれを試していました。1つはナビゲーションバー内にあり、もう1つはコンポーネントを収容するために体内にありました。これで、すべてを親コンポーネントの同じルーター内に配置すると、正常に機能します。
MatteusBarbosa19年

3
すばらしい-私の正確な問題。ありがとう
GeoffreyBourne20年

2
ありがとう!あなたは私を救いました!!
AzizStark

1
withRouterを含むすべてを試しましたが、このソリューションだけが機能しました...これが発生する理由を理解するのに少し説明が役立ちます
Jim

1
@Jim私が反応し、ルータは、コンテキストAPIを使用し、考える<Router />別名<BrowserRouter /> のようなルートマッチャにコンテキストを提供し<Route /><Switch /> 同様とナビゲーションコンポーネント<Link /><Redirect />。同じコンテキストを提供するには、コンテキストプロバイダー内のすべての子コンポーネントをラップする必要があり<Router />ます。
Yusufbek


5

BrowserRouterは、あなたのケースの履歴を維持できません。代わりに「ルーター」を使用してください。小道具としてカスタム履歴でこれを使用すると、問題の解決に役立つ場合があります。

import {Router, Route, Switch, withRouter } from "react-router-dom";
import Home from "./pages/Home";
import Profile from "./pages/Profile";
import {createBrowserHistory} from 'history';

export const customHistory = createBrowserHistory();  //This maintains custom history

class App extends Component {
  render() {
    return (
      <Router history={customHistory}>
        <Switch>
          <Route exact path="/" component={Home} />
          <Route exact path="/profile" component={Profile} />
        </Switch>
      </Router>
    );
  }
}

export default App;

次に、コンポーネントで、「アプリ」からcustomHistoryをインポートし、それを使用してナビゲートします。

customHistory.push('/pathname');

この助けを願っています!:)


1
noに必要exactあなたは属性を使用する場合Switch
KBT

4

インデックスルートにexactを追加する必要があり、それらのルートコンポーネントをdivで囲むのではなく、Switch fromreact-router-domを使用してルートを切り替えます。

import React from "react";
import ReactDOM from "react-dom";
import { Route, Switch } from 'react-router-dom';
import Users from "./components/Users";

import Details from "./components/Details";

ReactDOM.render((
  <div>
    <Switch>
        <Route path="/" component={Users} exact/>
        <Route path="/details" component={Details} />
    </Switch>
  </div>
), document.getElementById('app'))

3

React Routerバージョン4でも同様の問題が発生しました:

<Link />コンポーネントをクリックすると、URLは変更されますが、ビューは変更されません。

ビューの1つPureComponentは、Component(からインポートされたreact)ではなく使用していたため、それが原因でした。

を使用PureComponentしていたすべてのルートレンダリングコンポーネントを置き換えることでComponent、私の問題は解決しました。

(解決ソース:https//github.com/ReactTraining/react-router/issues/4975#issuecomment-355393785


1
ありがとう。それは私のためにそれを修正しました。しかし、ライブビューの変更を機能させるために、PureComponentではなくComponentから拡張する必要があったのはSwitchを含むコンポーネントだけでした。
Christiaan Westerbeek 2018年

1
純粋なコンポーネントをコンポーネントに変更しましたが、機能していません。
Kosalram RamaKrishnan19年

2

私はこのように解決した同様の問題に直面していました。それが機能していることを願っています。

コンポーネントでcomponentWillReceiveProps関数を使用する必要があります。

URLを呼び出して最初にリンクをクリックしたwww.example.com/content1/componentDidMount()が実行されます。

別のリンクをクリックすると、www.example.com / content2 /と言います。同じコンポーネントが呼び出されますが、今回は小道具が変更され、APIの呼び出しに使用できるcomponentWillReceiveProps(nextProps)の下でこの新しい小道具にアクセスできます。または、状態を空白にして新しいものを取得します。データ。

componentWillReceiveProps(nextProps){
     //call your API and update state with new props
}

1

うーん、実際にビューを切り替えるスイッチはありません。

これは私がルーターを使って着陸ページからメインサイトに切り替える方法です

//index.jsx    
ReactDOM.render( (<BrowserRouter><App/></BrowserRouter>), document.getElementById('root') );


//App.jsx
render()
{
    return <div>
        <Switch>
            <Route exact path='/' component={Lander}/>
            <Route path='/vadatajs' component={Vadatajs}/>
        </Switch>
    </div>
}

https://jsfiddle.net/Martins_Abilevs/4jko7arp/11/

ups私はあなたが別のルーターを使用していることを発見しました..申し訳ありませんが、多分このフィドルはあなたのために役立つでしょう

https://fiddle.jshell.net/terda12/mana88Lm/

たぶん、解決策の鍵は、メインのレンダリング機能のために一列に隠されています。

Router.run(routes, function(Handler) {
    React.render(<Handler />, document.getElementById('container'));
});

1

同じ問題が発生します。この場合、彼はルートで小道具を追加する必要はないと思います。NavLinkをチェックインして、適切なパス名を詳細として記述してください。ルートについては、特定のルートから一般的なルートへと開始してみてください。

<Route path="/details" component={Details} />
<Route path="/" component={Users} />

NavLinkでは次のようになります

 <NavLink className="nav-link" to="/details">
   details<span className="sr-only">(current)</span>
 </NavLink>

インポートのリマークは、Reactに関連するすべてのものをインポートしてから開始し、その後、次のような他のモジュールをインポートすることをお勧めします。

import React from "react";
import ReactDOM from "react-dom";
import { BrowserRouter } from 'react-router-dom';
import Users from "./components/Users";
import { Router, Route } from "react-router";
import Details from "./components/Details";

このように来る:

import React from "react";
import ReactDOM from "react-dom";
import { BrowserRouter } from 'react-router-dom';
import { Router, Route } from "react-router";

import Users from "./components/Users";    
import Details from "./components/Details";

1

私にとって、私は持っていました:

export MyClass extends React.Component

と:

export default withRouter(MyClass)

一方、私のApp.jsには、次のものがありました。

import { MyClass } from './MyClass'

ホームゲームをしている人は私の問題を見ることができます。ルーターが子クラスに渡された状態でインポートを取得していませんでした。これをクリーンアップするために、withRouter呼び出しをRouteコンポーネント宣言に移動しました

<Router exact path={'/myclass'} component={withRouter(MyClass)} />

MyClassに戻り、デフォルトのエクスポートに変更しました。

export default MyClass extends React.Component

そして最後に、App.jsで、インポートを次のように変更しました。

import MyClass from './MyClass'

うまくいけば、これは誰かを助けます。これにより、同じクラスをエクスポートする2つの方法がなかったため、withRouterの先頭をバイパスできます。


0

これを試して、

import React from "react";

import ReactDOM from "react-dom";
import Users from "./components/Users";
import { Router, Route } from "react-router";


import Details from "./components/Details";

ReactDOM.render((
  <Router>
        <Route path="/" component={Wrapper} >
            <IndexRoute component={Users} />
            <Route path="/details" component={Details} />
        </Route>
  </Router>
), document.getElementById('app'))

this.props.childrenをレンダリングするラッパーコンポーネントを定義します。これにより、正しくルーティングされます。
Vaibhav Singh

0

これをチェックする必要がありますhttps//github.com/ReactTraining/react-router/blob/master/packages/react-router/docs/guides/blocked-updates.md

したがって、UsersまたはDetailsではありません。これらは、によって直接レンダリングされ<Route>locationに渡されるためpropsです。

なぜとの<div>間が必要なのか疑問に思います。それを削除して、機能するかどうかを知らせてください。<BrowserRouter><Route>


0

条件付きレイアウトでも同様の問題が発生しました。

class LayoutSwitcher extends Component {
  render () {
    const isLoggedIn = this.props.isLoggedIn
    return (
      <React.Fragment>
        { isLoggedIn
          ? <MainLayout {...this.props} />
          : <Login />
        }
      </React.Fragment>
    )
  }
}

そして、そのように条件を書き直しました:

  render () {
    const isLoggedIn = this.props.isLoggedIn
    if (isLoggedIn) {
      return <MainLayout {...this.props} />
    }
    return <Login />
  }

これはそれを解決しました。私の場合、コンテキストが失われたようです。



0

同じ問題が発生し、node_modulesの@typesフォルダーから履歴をインポートする問題を修正しました。npmからインポートしました(npm i @history)


0

私も同じ問題を抱えていました。あまり効果的な解決策ではありませんが、狡猾な方法で解決しました。ComponentDidMountメソッドは、URLが変更されるたびに機能します。メソッド内で、前のURLと現在のURLを比較し、状態の変更またはページの更新を行うことができます。

componentDidUpdate(prevProps) {
    if (this.props.match.url !== prevProps.match.url) {
        //this.props.history.go(0) refresh Page
        //this.setState(...) or change state
    }
}

-1

私もトラブルに遭遇しました。

https://github.com/chengjianhua/templated-operating-system

そして、私はShubham Khatriによって提案された解決策を試しましたが、それは機能しません。


私はこの問題を解決しました、多分あなたを助けることができます。

https://github.com/ReactTraining/react-router/blob/master/packages/react-router/docs/guides/blocked-updates.md

使用時には、上記の案内文書を、従うPureComponentか、状態管理ツールで使用が好きreduxmobx...それはあなたのルートの更新をブロックすることがあります。ルートコンポーネントをチェックし、コンポーネントの再レンダリングをブロックしていないことを確認します。


-2

prop forceRefresh = {true}をBrowserRouter(Router)に追加してみてください

import {BrowserRouter as Router} from "react-router-dom";

<Router forceRefresh={true}>
/// your <switch> and <route>
</Router>

わたしにはできる。

ところで、それは本当の解決策ではありません:D

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.