React路由器更改URL但不查看

时间:2017-04-11 16:42:38

标签: reactjs react-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'))

当我使用网址/详细信息时,我的浏览器会导航到该网址,但不会更改视图。任何其他路线抛出404,因此它似乎识别路线但不更新。

26 个答案:

答案 0 :(得分:26)

您需要为indexRoute指定属性exact,否则对于偶数/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'))

更新:

您需要做的另一件事是使用withRouter附加您的组件用户。仅当您的组件未收到withRouter

时,才需要使用Router props

如果您的组件是由路由器呈现的组件的嵌套子项,或者您没有通过路由器道具,或者组件根本没有链接到路由器,而是作为路由的单独组件呈现。

在Users.js中添加

import {withRouter} from 'react-router';

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

<强> DOCS

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

答案 2 :(得分:13)

您只需要将组件包装在 withRouter 中。

<路由精确路径=“ / 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;

OR

您还可以在导出之前将组件包装在 withRouter 中,但随后必须确保其他一些事情。

export default withRouter(Profile)

答案 3 :(得分:5)

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

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

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

答案 4 :(得分: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;

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

customHistory.push('/pathname');

希望有帮助! :)

答案 5 :(得分:2)

您需要精确地添加到索引路由,而不是按div包围那些 Route 组件,而应使用react-router-dom中的 Switch 在这些路由之间进行切换。

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

答案 6 :(得分:2)

我尝试在主路径前添加“精确” 像这样

<块引用>

<Route exact path="/" component={Home}></Route>

它工作正常...

答案 7 :(得分:2)

我在使用 react-router-dom 5

时遇到了同样的问题

问题是由 history 包引起的。 我使用的版本是 5.0.0,但它们不能一起工作。

通过将 history 降级到 4.10.1 来修复

相关问题:https://github.com/ReactTraining/history/issues/804

答案 8 :(得分:1)

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

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

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

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

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

答案 9 :(得分:1)

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

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

第一次通过调用网址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
}

答案 10 :(得分: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 前缀。

答案 11 :(得分:0)

我建议您检查 User 和 Details 组件。他们不应该有一个路由器组件。如果您在它们内部使用 <Link to=../>,它位于 <Router> 内,请尝试移除路由器并仅使用链接。

答案 12 :(得分:0)

尝试将prop forceRefresh = {true}添加到BrowserRouter(Router)

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

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

对我有用。

这不是一个真正的解决方案:D

答案 13 :(得分:0)

我不小心在我的链接周围使用了 BrowserRouter。

<BrowserRouter>
    <div>
        <Link to="/" component={Users} />
        <Link to="/details" component={Details} />
    </div>
</BrowserRouter>

答案 14 :(得分:0)

我也有同样的问题。尽管这不是一个非常有效的解决方案,但我使用了一种狡猾的方法来解决它。 每当我们的网址更改时,ComponentDidMount方法就起作用。 在该方法中,我们可以将先前的URL与当前的URL进行比较,并可以进行状态更改或页面刷新。

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

答案 15 :(得分:0)

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

答案 16 :(得分:0)

GestureDetector(
    onVerticalDragEnd:(details) {print("drag ended");},
    child:DraggableScrollableSheet(
        initialChildSize: 0.75,
        minChildSize: 0.65,
        maxChildSize: 1.0,
        builder: (context, _scrollController) {
            return ListView(
                physics: ClampingScrollPhysics(),
                controller: _scrollController,
                children: [Widget A, Widget B, Widget C...],
            );
        },
    ),
)

我也遇到了使用 <Route exact path="/" component={Users} /> <Route exact path="/details" component={Details} /> 属性解决的相同问题。尝试使用 exact 属性。

答案 17 :(得分:0)

就我而言,切换到HashRouter而不是BrowserRouter解决了我的问题

答案 18 :(得分:0)

我遇到同样的问题。 我认为在这种情况下,他不需要添加带有路由器的道具, 只要检查您的NavLink,您就可以写出正确的路径名称作为详细信息。 对于该路线,请尝试从特定路线开始,再到一般路线

request

在您的NavLink中,应该是这样的

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

重新导入最好在导入其他模块后先导入与React相关的所有内容 像这样一个:

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

像这样来

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

答案 19 :(得分:0)

就我而言,我错误地嵌套了两个BrowserRouter

答案 20 :(得分:0)

我遇到了类似的问题,但结构不同。我添加了一个可以处理所有路由的路由器,并使用了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>

答案 21 :(得分: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 />
  }

这解决了。就我而言,似乎上下文丢失了。

答案 22 :(得分:0)

嗯,没有任何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'));
});

答案 23 :(得分:0)

你应该看一下:https://github.com/ReactTraining/react-router/blob/master/packages/react-router/docs/guides/blocked-updates.md

因此,它绝对不是UsersDetails,因为它们由<Route>直接呈现,location将传递给props

我想知道,为什么你需要<div><BrowserRouter>之间的<Route>?删除它,让我知道它是否有效。

答案 24 :(得分: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'))

答案 25 :(得分:0)

我也遇到了麻烦。

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等状态管理工具时...它可能会阻止您的路线更新。检查您的路线组件,确保您没有阻止组件的重新渲染。