反应路由器更改URL但不查看


81

我在更改视图以响应路由时遇到麻烦。我只想显示一个用户列表,单击每个用户应导航到详细信息页面。这是路由器:

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,因此似乎可以识别该路由,但无法更新。


我遇到两个错误:一个声明不赞成使用主react包中的原型。不推荐使用React.createClass的两个声明。我认为这无关紧要,因为代码无需使用路由即可工作。
MARyan87 '17

您的组件安装正确吗?
杰里米·约翰

Answers:


69

您需要exact为indexRoute指定属性,否则即使/details路由也将与匹配/。也尝试导入Routereact-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'))

更新:

您需要做的另一件事是使用附加用户组件withRouterwithRouter仅当您的组件未收到时,才需要使用Router props

如果您的组件是由路由器渲染的组件的嵌套子代,或者您没有将路由器道具传递给它,或者该组件根本没有链接到路由器,并且作为独立于该组件的组件呈现,则可能会发生这种情况路线。

在Users.js中添加

import {withRouter} from 'react-router';

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

DOCS


可以通过安装npm install -S 'prop-types'React.PropsTypes并将其替换为PropTypes来消除proptypes警告。还更新您的package.json以使用最新打包的软件包,因为其他软件包可能仍在使用React.PropTypes和React.createClass
Shubham Khatri

还您尝试在URL更改时重新加载页面以查看是否加载吗
Shubham Khatri

我没有尝试重新加载页面,它不会更改视图。即使网址为/#/ details,它也会加载到“用户”视图中
MARyan87 '17

1
您能尝试使用Route从'react-router-dom'而不是react-router
Shubham Khatri

如果尚未解决,请将您的用户组件与绑定withRouter,它可以帮助我解决之前的相同问题。让我知道。我也更新了代码。
Shubham Khatri

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;

额外

如果您使用的是React Router,则每当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
<路由确切路径=“ / mypath” component = {withRouter(MyComponent)} />对我有用
Santosh Kumar

13

我遇到了同样的问题,发现那是因为我有一个嵌套的路由器。一旦我删除了嵌套路由器,并将我特定于组件的路由放入交换机组件中,就可以解决该问题,而不必使用withRouter或进行任何其他更改。

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

优素福贝克(Yusufbek)正在描述类似的问题。我认为在视图级别存储与组件相关的路由比将它们全部存储在一个主路由器中要干净得多。在生产应用程序中,这将是太多的路线,以至于无法轻松阅读和调试问题。


13

我也遇到过同样的问题,但我已解决。我将主页放在最后。这个对我有用。就像下面一样。

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


4
使用该exact属性还将为您解决此问题。
isherwood

7

当使用Redux时,我遇到类似的问题,其中地址栏中的URL正在更新,但应用程序未加载相应的组件。我能够通过将withRouter添加到导出中来解决:

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

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

4

我有类似的问题,但结构不同。我添加了一个可以处理所有路由的路由器,并且使用了Switch组件来切换视图。但是实际上,事实并非如此。仅URL更改,但未更改。原因是在SideBar组件内部使用的Link组件,该组件在Router组件外部。(是的,我已经用“ withRouter”导出了SideBar,但是没有用)。因此,解决方案是将保存所有Link组件的SideBar组件移入Router。

问题出在我的链接器中,它们在我的路由器之外

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

1
帮助自己度过了美好的一天。我正在尝试使用两个分离的路由器。一种在导航栏中,另一种在体内,以适应组件。现在,我将所有内容放在父组件的同一路由器中,并且一切正常。
Matteus Barbosa

2
太好了-我的确切问题。谢谢
Geoffrey Bourne

1
谢谢!你救了我!!
AzizStark


4

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;

然后在您的组件中,从“ App”导入customHistory并使用它进行导航。

customHistory.push('/pathname');

希望对您有所帮助!:)


没有必要的exact,当您使用属性Switch
KBT

3

您需要向索引路由中添加精确的路由,而不是通过div封闭那些Route组件,而使用Switch from react-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'))

2

我对React Router版本4有类似的问题:

通过单击<Link />组件,URL会更改,但视图不会更改。

其中一种观点是使用PureComponent而不是Component(从导入react),这就是原因。

通过替换所有使用PureComponent到的路线渲染组件Component,我的问题得以解决。

(解决方案来源:https : //github.com/ReactTraining/react-router/issues/4975#issuecomment-355393785


谢谢。这为我解决了。但这只是包含Switch的组件,我必须从Component而不是PureComponent进行扩展,以使实时视图能够正常工作。
克里斯蒂安·韦斯特贝克

我已经将纯组件更改为组件,但是它对我不起作用。
Kosalram Rama Krishnan

1

嗯,没有任何SWITCH可以实际切换视图。

这就是我使用路由器从登陆页面切换到主站点的方式

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

我面临类似的问题,我决心要解决这个问题,请看一下,希望它能正常工作。

您需要在组件中使用componentWillReceiveProps函数。

通过调用url第一次单击链接www.example.com/content1/ componentDidMount()运行。

现在,当您单击另一个链接时,说www.example.com/content2/,将调用相同的组件,但是这次prop发生了变化,您可以在componentWillReceiveProps(nextProps)下访问此新prop,可用于调用API或将状态设为空白并获取新的数据。

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

1

对我来说,我有:

export MyClass extends React.Component

与:

export default withRouter(MyClass)

同时,在我的App.js中,我有:

import { MyClass } from './MyClass'

那些玩家庭游戏的人可以看到我的问题。我没有通过将Router传递到子类中来进行导入。为了解决这个问题,我将withRouter调用移至Route组件声明中:

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

回到MyClass,我将其更改为默认导出:

export default MyClass extends React.Component

最后,在App.js中,我将导入更改为:

import MyClass from './MyClass'

希望这对某人有帮助。这样可以确保我没有两种方法可以导出相同的类,从而绕过了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

我在条件布局上遇到了类似的问题:

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

我遇到同样的问题。我认为在这种情况下,他不需要添加带路由器的prop,只需在您的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";


0

我遇到了同样的问题,并修复了从node_modules中的@types文件夹导入历史记录的问题。我从npm导入(npm i @history)


-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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.