对路由器更改 url 而不是 view 作出反应

我有麻烦改变的看法与路由的反应。我只想显示一个用户列表,点击每个用户应该导航到一个详细信息页面。这是路由器:

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,所以它似乎认识的路线,但不更新。

147039 次浏览

您需要为 indexRoute 指定属性 exact,否则即使对于 /details路由,它也将与 /匹配。还要尝试从 react-router-dom导入 Route

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连接起来。只有当组件没有接收到 Router props时,才需要使用 withRouter,

当组件是 由路由器呈现的组件的嵌套子级你还没把路由器的道具传给它,或者组件根本没有链接到路由器,而是作为独立于路由器的组件呈现时,可能会出现这种情况。

在 Users.js 中添加

import {withRouter} from 'react-router';


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

医生

我也遇到了麻烦。

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... 它可能会阻止更新您的路由。检查您的路由组件,确保您没有阻止您的组件的重新呈现。

试试这个,

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

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

因此它肯定不是 UsersDetails,因为它们是由 <Route>直接呈现的,而 location将被传递给 props

我想知道,为什么你需要 <BrowserRouter><Route>之间的 <div>?把它取下来,如果有用就告诉我。

嗯,没有任何切换来切换视图。

这是我如何使用路由器切换从登陆页面到主站点

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

我发现你使用不同的路由器。对不起,那么也许这个小提琴对你有用

Https://fiddle.jshell.net/terda12/mana88lm/

也许解决的关键是隐藏在线的主要渲染功能。

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

我对 React 路由器版本4也有类似的问题:

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

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

通过替换所有使用 PureComponentComponent的路由渲染组件,我的问题得到了解决。

(分辨率来源: https://github.com/ReactTraining/react-router/issues/4975#issuecomment-355393785)

您需要精确地添加到索引路由,而不是通过 div 封装这些 路线组件,使用 response-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'))

您只需要将组件包装在 路由器中。

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

附加条款

如果您使用的是反应路由器,组件 WillReceiveProps将被调用时,网址变化。

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

注意

或者,您也可以在导出之前将组件包装在 路由器中,但是之后您必须确保一些其他的事情。我通常会跳过这一步。

export default withRouter(Profile)

在使用 Redux 时,我遇到了类似的问题,即 URL 在地址栏中更新,但应用程序没有加载相应的组件。我可以通过在导出中加入路由器来解决这个问题:

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


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

我正面临着类似的问题,我决心喜欢这一点,请看看,我希望它的工作。

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

通过调用 url www.example.com/content1/组件第一次单击一个链接。

现在,当你点击另一个链接,说 www.example.com/content2/同一个组件被调用,但是这次道具改变了,你可以访问这个新的道具组件 WillReceiveProps (nextProps) ,你可以使用它来调用 API 或者使状态为空并获得新的数据。

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

我对条件布局也有类似的问题:

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

这就解决了,在我的案子里,似乎没有上下文了。

我也有过类似的问题,只是结构不同。我已经添加了一个路由器,将处理所有的路由,我已经使用交换组件切换视图。但事实上,并没有。只更改了 URL,但没有查看。出现这种情况的原因是 SideBar 组件内部使用的 Link 组件位于路由器组件之外。(是的,我已经用“ withRouter”导出了 SideBar,但没有成功)。 所以,解决方案是将我的 SideBar 组件,所有的 Link 组件移动到我的路由器中。

问题出在我的连接器上,它们在我的路由器外面

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

在我的例子中,我错误地嵌套了两个 BrowserRouter

我有同样的问题,并发现这是因为我有一个嵌套的路由器。一旦我删除了嵌套的路由器,并简单地将我的组件特定的路由放在一个交换机组件中——这个问题就解决了,不需要使用路由器或做任何其他更改。

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

Yusufbek 描述了一个类似的问题。我认为将组件相关路由存储在一个视图级别比将所有组件存储在一个主路由器中要干净得多。在一个生产应用程序中,有太多的路由可以很容易地读取和调试问题。

我也遇到过同样的问题,但我解决了。我把主页作为最后一页。对我有用。就像下面一样。

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

我也有同样的问题。 我不认为在这种情况下他需要添加路由器的道具, 只要检查你的导航链接,你写好的路径名称作为细节。 为路线尝试从具体的路线到一般的一样

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

你的导航链接应该是这样的

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

在我的例子中,切换到 HashRouter 而不是 BrowserRouter 解决了我的问题

在您的情况下,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');

希望这有帮助! :)

我也有同样的问题,所以我修复了从 node _ module 中的@type 文件夹导入历史记录的问题。我从 npm (npm i@history)导入了它

对我来说,我有:

export MyClass extends React.Component

与:

export default withRouter(MyClass)

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

import { MyClass } from './MyClass'

那些玩主场游戏的人能看出我的问题。我没有得到与路由器的导入传递到子类。为了解决这个问题,我将 路由器调用移到 Route 组件声明中:

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

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

export default MyClass extends React.Component

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

import MyClass from './MyClass'

希望这能帮到别人。这样可以确保不会有两种方法导出同一个类,从而绕过 路由器预置。

我也有同样的问题。虽然这不是一个非常有效的解决办法,我解决了它与狡猾的方法。 组件 DidMount 方法在我们的 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
}
}

我不小心用了一个浏览器路由器。

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

我建议您检查用户和详细信息组件。它们不应该包含路由器组件。如果你使用 <Link to=../>在他们里面,这是在一个 <Router>尝试删除路由器,只使用链接。

我试着在回家路前加上“精确” 像这样

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

它工作得很好..。

我对 react-router-dom 5也有同样的问题

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

通过降级 history4.10.1来修正

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

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

我也面临着同样的问题,这个问题是用 exact属性解决的。

如果你最近才开始遇到这个问题,看看 https://github.com/remix-run/react-router/issues/7415

这个问题是与反应路由器 -dom 5 + 和历史相关性。

如果您使用 yarn install history单独安装它,您需要卸载它,执行 yarn install history@4.10.1

如果有人使用 history软件包导航,如果您使用的是 react-router v5,那么您可能必须将 history软件包降级到 4.10.1,直到 history软件包开发人员发布新版本的修复程序。在撰写本文时,history软件包的最新版本是 v5.0.1,如果您看到比这个版本更新的版本,您可以首先尝试使用这个版本,看看它是否有效,然后再降级到 4.10.1

发行链接-> https://github.com/remix-run/history/issues/804

如果像上面的例子一样配置路由器组件,并尝试从任何组件访问 history. push 或 prop.history. push,那么可能会面临在更改 URL 时不呈现组件的问题。您可以通过直接从 response-Router-dom 导入路由器来修复这个问题,而不是将 BrowserRouter 导入为路由器。您可以在下面找到更正的代码。

例如: import { 路由器, 开关, 路线, 来自“反应路由器王国”;

不要: 进口{ 作为路由器的浏览器路由器, 开关, 路线, 来自“反应路由器王国”;

我突然想到一个老问题。

OP 的 <Switch>代码块在引用的代码中丢失了。这肯定会使事情无法正常工作。

这里的所有答案都没有解决我的问题,结果我不得不在我的 useEffect钩子中添加一个依赖项。我有这样的东西:

App.js

<Route
path="/product/:id"
component={MyComponent}
/>

MyComponent.jsx

const { id } = useParams();


useEffect(() => {
fetchData();
}, []);

我有一个按钮改变到另一个产品,这只会更新的 :id的网址,我可以看到的网址改变,但没有影响的网页。这一变化解决了这一问题:

MyComponent.jsx

const { id } = useParams();


useEffect(() => {
fetchData();
}, [id]); // add 'id' to dependency array

现在,当 id发生变化时,它触发一个函数来更新数据并按预期工作。

React 路由器 v5与 React 18 StrictMode 无法工作 Https://github.com/remix-run/react-router/issues/7870

根据这个问题 给你,由于 BrowserRouter 是 StrictMode 的子代,因此 response-router-dom 与 React 18不兼容。

为了解决这个问题。

而不是这样:

<React.StrictMode><BrowserRouter>...</BrowserRouter></React.StrictMode>

这样做:

<BrowserRouter><React.StrictMode>...</React.StrictMode></BrowserRouter>

这种方式对我很有效,希望能有帮助。

在我的例子中,它不工作,因为我导入了 Browser 路由器作为路由器,像这样:

<Router>


<div> <Navbar/></div>


<Routes>
<Route exact path="/" element={<Pageone/>}></Route>
<Route  path="/home" element={<Home/>}></Route>
<Route  path="/about" element={<About/>}></Route>
<Route  path="/contact" element={<Contact/>}></Route>
</Routes>


    

<div><Footer /></div>




</Router>
</div>
  

然后通过添加 BrowserRouter 来修复:

 <BrowserRouter>


<div> <Navbar/></div>


<Routes>
<Route exact path="/" element={<Pageone/>}></Route>
<Route  path="/home" element={<Home/>}></Route>
<Route  path="/about" element={<About/>}></Route>
<Route  path="/contact" element={<Contact/>}></Route>
</Routes>


    

<div><Footer /></div>




</BrowserRouter>
</div>
  

希望这对谁有帮助!

我在 react router v6中遇到过类似的问题,原来我使用的是没有 <Outlet/>组件的嵌套路由,所以当我单击嵌套子路由时,URL 发生了变化,但是什么也没有发生?

这完全是因为我没有告诉它在父组件中的哪里呈现子组件,这显然是使用 <Outlet/>组件完成的。