Reagieren Router ändert URL, aber nicht anzeigen

81

Ich habe Probleme, die Ansicht zu ändern, wenn ich auf das Routing reagiere. Ich möchte nur eine Liste der Benutzer anzeigen, und durch Klicken auf jeden Benutzer sollte zu einer Detailseite navigiert werden. Hier ist der Router:

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'))

Wenn ich die URL / Details verwende, navigiert mein Browser zu dieser URL, ändert jedoch nicht die Ansicht. Jede andere Route wirft 404, sodass sie die Route zu erkennen scheint, aber nicht aktualisiert.

MARyan87
quelle
Ich erhalte zwei Fehler: Einer besagt, dass die Verwendung von Proptypen aus dem Hauptreaktionspaket veraltet ist. Zwei Angaben mit React.createClass sind veraltet. Ich dachte, dass dies nichts damit zu tun hat, da der Code ohne Routing funktioniert.
MARyan87
Ist Ihre Komponente richtig montiert?
Jeremy John

Antworten:

69

Sie müssen das Attribut exactfür Ihre indexRoute angeben, andernfalls stimmt es für eine gerade /detailsRoute weiterhin überein /. Versuchen Sie auch, Routeaus zu importierenreact-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'))

AKTUALISIEREN:

Eine andere Sache, die Sie tun müssen, ist, Ihre Komponentenbenutzer mit anzuhängen withRouter. Sie müssen withRouternur verwenden, wenn Ihre Komponente nicht die Router props,

Dies kann vorkommen, wenn Ihre Komponente ein verschachteltes untergeordnetes Element einer vom Router gerenderten Komponente ist oder Sie die Router-Requisiten nicht an sie übergeben haben oder wenn die Komponente überhaupt nicht mit dem Router verbunden ist und als separate Komponente von gerendert wird die Routen.

In Users.js hinzufügen

import {withRouter} from 'react-router';

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

DOCS

Shubham Khatri
quelle
Die Warnung zu den Proptypen kann entfernt werden, npm install -S 'prop-types'indem React.PropsTypes installiert und durch PropTypes ersetzt wird. Aktualisieren Sie auch Ihre package.json, um die neuesten Pakete zu verwenden, da andere Pakete möglicherweise noch React.PropTypes und React.createClass
Shubham Khatri verwenden.
Versuchen Sie auch, die Seite neu zu laden, wenn sich die URL ändert, um zu sehen, ob sie
geladen wird
Ich habe versucht, die Seite neu zu laden. Die Ansicht wird dadurch nicht geändert. Es wird in die Benutzeransicht
geladen,
1
Können Sie die aktualisierte Antwort mit Routeimportiert von "React-Router-Dom" anstelle vonreact-router
Shubham Khatri
Wenn es noch nicht gelöst ist, binden Sie Ihre Benutzerkomponente an withRouter. Es hat mir zuvor geholfen, das gleiche Problem zu lösen. Gib mir Bescheid. Ich habe den Code auch aktualisiert.
Shubham Khatri
27

Sie müssen nur die Komponenten mit Router einwickeln .

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

Hier ist ein Beispiel für eine App.js-Datei:

...
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;

Zusätzlich

Wenn Sie einen Reaktionsrouter verwenden, wird componentWillReceiveProps aufgerufen, wenn sich die URL ändert.

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

Hinweis

Alternativ können Sie die Komponente auch vor dem Export in withRouter einbinden , müssen dann aber noch einige andere Dinge sicherstellen. Normalerweise überspringe ich diesen Schritt.

export default withRouter(Profile)
Codierungselemente
quelle
3
<Route genaue path = "/ mypath" component = {withRouter (MyComponent)} /> arbeitete für mich
Santosh Kumar
13

Ich hatte das gleiche Problem und stellte fest, dass es daran lag, dass ich einen verschachtelten Router hatte. Nachdem ich den verschachtelten Router entfernt und meine komponentenspezifischen Routen einfach in eine Switch-Komponente eingefügt hatte, wurde das Problem behoben, ohne dass ich WithRouter verwenden oder zusätzliche Änderungen vornehmen musste.

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

Yusufbek beschreibt ein ähnliches Problem. Ich denke, es ist viel sauberer, die komponentenbezogenen Routen auf Ansichtsebene zu speichern, als sie alle in einem Hauptrouter zu speichern. In einer Produktions-App sind dies viel zu viele Routen, um Probleme einfach durchzulesen und zu beheben.

Ryan Brockhoff
quelle
13

Ich habe das gleiche Problem, aber ich habe es behoben. Ich habe die Homepage als letzte platziert. Für mich geht das. Genau wie unten.

    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'))

Shahab Khan
quelle
4
Die Verwendung der exactEigenschaft hätte dies auch für Sie behoben.
Isherwood
7

Bei der Verwendung von Redux und mir gab es ähnliche Probleme, bei denen die URL in der Adressleiste aktualisiert wurde, die App jedoch die entsprechende Komponente nicht lud. Ich konnte lösen, indem ich withRouter zum Export hinzufügte:

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

export default withRouter(connect(mapStateToProps)(MyComponentName))
Bruce Seymour
quelle
4

Ich hatte ein ähnliches Problem, aber mit unterschiedlicher Struktur. Ich habe einen Router hinzugefügt, der alle Routen verarbeitet. Ich habe die Switch-Komponente verwendet, um die Ansichten zu wechseln. Aber eigentlich nicht. Nur URL geändert, aber nicht angezeigt. Der Grund dafür war die Link-Komponente, die innerhalb der SideBar-Komponente außerhalb der Router-Komponente verwendet wurde. (Ja, ich habe SideBar mit "withRouter" exportiert, nicht funktioniert). Die Lösung bestand also darin, meine SideBar-Komponente, die alle Link-Komponenten enthält, in meinen Router zu verschieben.

Das Problem liegt in meinen Linkern, sie befinden sich außerhalb meines Routers

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

Die Lösung bestand darin, meine Linker in meinen Router zu verschieben

<div className="_wrapper">
  <Router>
     <SideBar /> // Holds my all linkers
     <Switch>
       <Route path="/" component={Home} />
       <Route path="/users" component={Users} />
     </Switch>
  </Router>
</div>
Yusufbek
quelle
1
Sich selbst zu helfen machte meinen Tag. Ich habe es mit zwei getrennten Routern versucht. Eine befand sich innerhalb der Navigationsleiste und eine innerhalb des Körpers, um die Komponente aufzunehmen. Jetzt habe ich alles innerhalb desselben Routers in die übergeordnete Komponente eingefügt und die Dinge funktionieren so, wie sie sollten.
Matteus Barbosa
2
Ausgezeichnet - mein genaues Problem. Vielen Dank
Geoffrey Bourne
1
Vielen Dank! Du hast mich gerettet!!
AzizStark
4

In meinem Fall hatte ich fälschlicherweise zwei BrowserRouters verschachtelt .

Karuhanga
quelle
4

BrowserRouter kann den Verlauf in Ihrem Fall nicht verwalten. Verwenden Sie stattdessen "Router". Die Verwendung dieses Routers mit benutzerdefiniertem Verlauf als Requisiten kann zur Lösung Ihres Problems beitragen.

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;

Importieren Sie dann in Ihren Komponenten customHistory aus 'App' und navigieren Sie damit.

customHistory.push('/pathname');

Ich hoffe das hilft! :) :)

Anglesvar Cheenu
quelle
Das exactAttribut ist bei Verwendung nicht erforderlichSwitch
KBT
3

Sie müssen der Indexroute genau hinzufügen und anstatt diese Routenkomponenten durch div einzuschließen, verwenden Sie Switch from react-router-dom, um zwischen den Routen zu wechseln.

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'))
Vinay J Rao
quelle
2

Ich hatte ein ähnliches Problem mit React Router Version 4:

Durch Klicken auf die <Link />Komponente würde sich die URL ändern, die Ansichten jedoch nicht.

Eine der Ansichten wurde PureComponenteher verwendet als Component(importiert von react) und das war die Ursache.

Durch Ersetzen aller routengerenderten Komponenten, die verwendet wurden PureComponent, Componentwurde mein Problem behoben.

(Auflösungsquelle: https://github.com/ReactTraining/react-router/issues/4975#issuecomment-355393785 )

Kunok
quelle
Vielen Dank. Das hat es für mich behoben. Aber es war nur die Komponente, die Switch enthielt, die ich von Component anstelle von PureComponent erweitern musste, damit die Live-Ansicht funktioniert.
Christiaan Westerbeek
Ich habe meine reine Komponente in Komponente geändert, aber es funktioniert bei mir nicht.
Kosalram Rama Krishnan
1

Hmm, es gibt keinen Schalter, um die Ansicht zu wechseln.

Auf diese Weise verwende ich den Router, um von der Landin-Seite zur Hauptseite zu wechseln

//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/

Ich habe festgestellt, dass Sie einen anderen Router verwenden. Tut mir leid, dann ist diese Geige vielleicht für Sie nützlich

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

Vielleicht ist der Schlüssel der Lösung in der Linie für die Hauptrenderfunktion ausgeblendet.

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

Ich hatte ein ähnliches Problem, das mir gefällt. Bitte schauen Sie es sich an. Ich hoffe, es funktioniert.

Sie müssen die Funktion componentWillReceiveProps in Ihrer Komponente verwenden.

Klicken Sie zum ersten Mal auf einen Link, indem Sie die URL aufrufen. www.example.com/content1/ componentDidMount () wird ausgeführt.

Wenn Sie jetzt auf einen anderen Link klicken, sagen Sie www.example.com/content2/, dass dieselbe Komponente aufgerufen wird, aber diesmal ändert sich die Requisite und Sie können auf diese neue Requisite unter componentWillReceiveProps (nextProps) zugreifen, mit der Sie die API aufrufen oder den Status leer machen und neu erhalten können Daten.

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

Für mich hatte ich:

export MyClass extends React.Component

mit:

export default withRouter(MyClass)

Inzwischen hatte ich in meiner App.js:

import { MyClass } from './MyClass'

Diejenigen, die das Heimspiel spielen, können mein Problem sehen. Ich habe den Import nicht erhalten, da der Router an die untergeordneten Klassen übergeben wurde. Um dies zu bereinigen, habe ich den withRouter- Aufruf in die Route-Komponentendeklaration verschoben :

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

Zurück in MyClass habe ich es in einen Standardexport geändert:

export default MyClass extends React.Component

Und schließlich habe ich in App.js meinen Import geändert in:

import MyClass from './MyClass'

Hoffentlich hilft das jemandem. Dies stellt sicher, dass ich nicht zwei Möglichkeiten hatte, dieselbe Klasse zu exportieren, wodurch das withRouter-Präfix umgangen wurde .

Codenova
quelle
0

Versuche dies,

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'))
Vaibhav Singh
quelle
Definieren Sie eine Wrapper-Komponente, die this.props.children rendert. Dies wird ordnungsgemäß weitergeleitet.
Vaibhav Singh
0

Ich hatte ein ähnliches Problem mit einem bedingten Layout:

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

und schrieb die Bedingungen wie folgt um:

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

Das hat es gelöst. In meinem Fall scheint der Kontext verloren gegangen zu sein.

sym
quelle
0

Ich bekomme das gleiche Problem. Ich glaube nicht, dass er in diesem Fall die Requisite mit Router hinzufügen muss. Überprüfen Sie einfach Ihren NavLink, und schreiben Sie den guten Pfadnamen als Details. Versuchen Sie für die Route, von der spezifischen Route zur allgemeinen Route zu beginnen

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

In Ihrem NavLink sollte es so etwas sein

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

Eine Bemerkung für den Import Es ist besser, zunächst alle mit React zusammenhängenden Dinge zu importieren, nachdem Sie das andere Modul wie dieses importiert haben:

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";

komm so:

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";
KBT
quelle
0

In meinem Fall löste der Wechsel zu HashRouter anstelle von BrowserRouter mein Problem

lloyd agola
quelle
0

Ich hatte das gleiche Problem und habe es behoben, indem ich den Verlauf aus dem Ordner @types in node_modules importierte. Ich habe es von npm importiert (npm i @history)

Nico
quelle
-1

Ich habe auch Ärger gemacht.

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

Und ich habe die Lösungen von Shubham Khatri ausprobiert, aber es funktioniert nicht.


Ich habe dieses Problem gelöst, kann Ihnen vielleicht helfen.

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

Nach dem obigen Führungs Dokument, wenn Sie PureComponentoder Statusverwaltung Verwendung mit Tool wie redux, mobxkann ... Es blockiert die Aktualisierung Ihrer Route. Überprüfen Sie Ihre Routenkomponente und stellen Sie sicher, dass Sie den Renderer Ihrer Komponente nicht blockiert haben.

Jianhua Cheng
quelle
-2

versuchen Sie, prop forceRefresh = {true} zu BrowserRouter (Router) hinzuzufügen

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

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

Für mich geht das.

Übrigens ist es keine echte Lösung: D.

Oarkon
quelle