React router changes url but not view

ReactjsReact Router

Reactjs Problem Overview


I am having trouble changing the view in react with routing. I only want to show a list of users, and clicking on each user should navigate to a details page. Here is the 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'))

When I use the url /details my browser navigates to that url, but does not change the view. Any other route throws 404 so it seems to recognize the route but not update.

Reactjs Solutions


Solution 1 - Reactjs

You need to specify the attribute exact for your indexRoute, otherwise for even /details route it will still match with / . Also try to import Route from 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'))

UPDATE:

Another thing that you need to do is to attach your component Users with withRouter. You need to make use of withRouter only when your component is not receiving the Router props,

This may happen in cases when your component is a nested child of a component rendered by the Router or you haven't passed the Router props to it or when the component is not linked to the Router at all and is rendered as a separate component from the Routes.

In Users.js add

import {withRouter} from 'react-router';

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

DOCS

Solution 2 - Reactjs

You just have to wrap the components inside withRouter.

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

Here is a sample App.js file:

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

Additional

If you are using react router, componentWillReceiveProps will get called whenever the url changes.

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

Note

Alternatively, you may also wrap the component in withRouter before exporting, but then you have to ensure a few other things. I usually skip this step.

export default withRouter(Profile)

Solution 3 - Reactjs

I had the same issue and discovered that it was because I had a nested router. Once I removed the nested router, and simply put my component-specific routes within a switch component--the issue was resolved without having to use withRouter or make any additional changes.

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

Yusufbek is describing a similar issue. I think it's a lot cleaner to store the component related routes at a view level versus storing all of them in one main router. In a production app, that's going to be way too many routes to easily read through and debug issues.

Solution 4 - Reactjs

I have faced the same problem but I fixed it. I have placed the home page as the last. It works for me. Just like below.

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

Solution 5 - Reactjs

I had a similar issue but with different structure. I've added one Router that will handle all routes, I've used Switch component to switch views. But actually, it didn't. Only URL changed but not view. The reason for this was the Link component used inside of SideBar component which was outside of the Router component. (Yes, I've exported SideBar with "withRouter", not worked). So, the solution was to move my SideBar component which holds, all Link components into my Router.

The problem is in my linkers, they are outside of my router

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

Solution was moving my linkers into my router

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

Solution 6 - Reactjs

I had the same issue with react-router-dom 5

The problem was caused by the history package. The version I was using was 5.0.0 but they don't work together.

Fixed by downgrading history to 4.10.1

Related issue: https://github.com/ReactTraining/history/issues/804

Solution 7 - Reactjs

BrowserRouter fails to maintain history in your case. Use "Router" instead, Usage of this with custom history as props may help resolve your problem.

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;

Then in your components, import customHistory from 'App' and use that to navigate.

customHistory.push('/pathname');

Hope This help! :)

Solution 8 - Reactjs

React Router v5 doesn't work with React 18 StrictMode https://github.com/remix-run/react-router/issues/7870

Solution 9 - Reactjs

When using Redux and I had similar issues where the url was updating in the address bar but the app was not loading the respective component. I was able to solve by adding withRouter to the export:

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

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

Solution 10 - Reactjs

In my case, I'd mistakenly nested two BrowserRouters.

Solution 11 - Reactjs

You need to add exact to the index route and rather than enclosing those Route components by div, use Switch from react-router-dom to switch between the routes.

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

Solution 12 - Reactjs

I had similar issue with React Router version 4:

By clicking <Link /> component, URL would change but views wouldn't.

One of views was using PureComponent rather than Component (imported from react) and that was the cause.

By replacing all route rendered components that were using PureComponent to Component, my issue was resolved.

(Resolution source: https://github.com/ReactTraining/react-router/issues/4975#issuecomment-355393785)

Solution 13 - Reactjs

I Tried adding "exact" in front of the home path like this

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

It is working fine...

Solution 14 - Reactjs

Hmm there no any SWITCH to actually switch views.

this is how i use router to switch from landin page to main site

//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 i found you use different router ..sorry then maybe this fiddle be for you useful

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

maybe key of solution is hiden in line for main render function ..

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

Solution 15 - Reactjs

I was facing similar issue I resolve to like this please have a look I hope it's working.

You need to use componentWillReceiveProps function in your component.

clicked a link first time by calling url www.example.com/content1/ componentDidMount() is run.

Now when you click another link say www.example.com/content2/ same component is called but this time prop changes and you can access this new prop under componentWillReceiveProps(nextProps) which you can use to call API Or make state blank and get new data.

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

Solution 16 - Reactjs

For me, I had:

export MyClass extends React.Component

with:

export default withRouter(MyClass)

Meanwhile, in my App.js, I had:

import { MyClass } from './MyClass'

Those playing the home game can see my problem. I was not getting the import with the Router passed into the child classes. To clean this up, I moved the withRouter call into the Route component declaration:

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

Back in MyClass, I changed it to a default export:

export default MyClass extends React.Component

And then finally, in App.js, I changed my import to:

import MyClass from './MyClass'

Hopefully this helps someone. This ensures I didn't have two ways to export the same class, thus bypassing the withRouter prepend.

Solution 17 - Reactjs

I also had the same problem. Although it is not a very effective solution, I solved it with a cunning method. The ComponentDidMount method works every time our url changes. Within the method we can compare the previous url with the current url and we can the state change or page refresh.

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

Solution 18 - Reactjs

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

I was also facing the same issue which was resolved using the exact attribute. try to use the exact attribute.

Solution 19 - Reactjs

According to this issue here, react-router-dom isn't compatible with React 18 because BrowserRouter is a child of StrictMode.

So to resolve the issue.

Instead of this:

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

Do this:

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

It worked for me this way, I hope it helps.

Solution 20 - Reactjs

I met trouble too.

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

And I have tried the solutions metioned by Shubham Khatri, but It doesn't work.


I solved this problem, maybe can help you.

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

According the above guide document, when you use PureComponent or use with state management tools like redux, mobx ... It may block the update of your route. Check your route component, ensure you did't block the rerender od your component.

Solution 21 - Reactjs

You should check this out: https://github.com/ReactTraining/react-router/blob/master/packages/react-router/docs/guides/blocked-updates.md

Therefore it's definitely not Users or Details, because they are directly rendered by <Route>, and the location will get passed to props.

I am wondering, why do you need the <div> between <BrowserRouter> and <Route>? Remove that and let me know if it works.

Solution 22 - Reactjs

I had a similar issue with a conditional Layout:

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

and rewrote the conditions like so:

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

This solved it. In my case, it seems that the context was lost.

Solution 23 - Reactjs

I get the same Issue. I don't think that in this case he needs to add the prop withRouter, just check in your NavLink you write the good path name as details. for the route try to start from the specific route to the general one like

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

in your NavLink it should be something like this

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

a remarque for the import its better to start by importing all stuff related to React after that import the other module like this one:

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

come like this:

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

Solution 24 - Reactjs

In my case, switching to HashRouter instead of BrowserRouter solved my issue

Solution 25 - Reactjs

I was accidentally using a BrowserRouter around my Link's.

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

Solution 26 - Reactjs

If you just started having this issue recently, take a look at https://github.com/remix-run/react-router/issues/7415

The issue is with react-router-dom 5+ and the history dependency.

If you installed it separately using yarn install history you need to uninstall it, do yarn install [email protected]

Solution 27 - Reactjs

None of the answers here solved my issue, turns out I had to add a dependency to my useEffect hook. I had something like this:

App.js

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

MyComponent.jsx

const { id } = useParams();

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

I had a button to change to another product, which would only update the :id on the url, I could see the url changed, but no effect on the page. This change fixed the issue:

MyComponent.jsx

const { id } = useParams();

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

Now when the id changes, it trigger a function to update the data and works as expected.

Solution 28 - Reactjs

Try this,

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

Solution 29 - Reactjs

I had the same issue and I fixed it importing the history from the @types folder in node_modules. I imported it from npm (npm i @history)

Solution 30 - Reactjs

I would suggest that you check the User and Details components. They should not have a Router component in them. If you are using a <Link to=../> inside them which is inside a <Router> try removing the Router and only use the Link.

Solution 31 - Reactjs

If anyone is using the history package for navigation and if you are using the react-router v5, then you may have to downgrade the history package to 4.10.1 until the history package developers issue a new release with the fix. As of writing this, the latest release version of history package is v5.0.1, and if you see a new release than this, you can try with that version first to see if it works, before doing the downgrade to 4.10.1

Issue Link -> https://github.com/remix-run/history/issues/804

Solution 32 - Reactjs

If you configure the router component like the above example and try to access history.push or props.history.push from any component, you may face the issue of not rendering the component while changing the URL. You can fix this by importing Router directly from react-router-dom instead of importing BrowserRouter as Router. You can find the corrected code below.

for e.g: import { Router, Switch, Route, } from "react-router-dom";

not: import { BrowserRouter as Router, Switch, Route, } from "react-router-dom";

Solution 33 - Reactjs

Just came across this old questsion.

OP's <Switch> block is missing there on the quoted code. That should definitely stop things from working properly.

Solution 34 - Reactjs

try to add prop forceRefresh={true} to BrowserRouter(Router)

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

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

it works for me.

btw its not a real solution :D

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMARyan87View Question on Stackoverflow
Solution 1 - ReactjsShubham KhatriView Answer on Stackoverflow
Solution 2 - ReactjsCoding ElementsView Answer on Stackoverflow
Solution 3 - ReactjsRyan BrockhoffView Answer on Stackoverflow
Solution 4 - ReactjsShahab KhanView Answer on Stackoverflow
Solution 5 - ReactjsYusufbekView Answer on Stackoverflow
Solution 6 - ReactjsHomeIsWhereThePcIsView Answer on Stackoverflow
Solution 7 - ReactjsAnglesvarView Answer on Stackoverflow
Solution 8 - ReactjsThomasView Answer on Stackoverflow
Solution 9 - ReactjsBruce SeymourView Answer on Stackoverflow
Solution 10 - ReactjsKaruhangaView Answer on Stackoverflow
Solution 11 - ReactjsVinay J RaoView Answer on Stackoverflow
Solution 12 - ReactjsKunokView Answer on Stackoverflow
Solution 13 - ReactjsYuthies DesignersView Answer on Stackoverflow
Solution 14 - ReactjsMartin AbilevView Answer on Stackoverflow
Solution 15 - ReactjsSanat GuptaView Answer on Stackoverflow
Solution 16 - ReactjsBoyardeeView Answer on Stackoverflow
Solution 17 - ReactjsAli YıldızözView Answer on Stackoverflow
Solution 18 - ReactjsRahul MoreView Answer on Stackoverflow
Solution 19 - ReactjsEbukaView Answer on Stackoverflow
Solution 20 - ReactjsJianhua ChengView Answer on Stackoverflow
Solution 21 - ReactjsyujiView Answer on Stackoverflow
Solution 22 - ReactjssymView Answer on Stackoverflow
Solution 23 - ReactjsKBTView Answer on Stackoverflow
Solution 24 - Reactjslloyd agolaView Answer on Stackoverflow
Solution 25 - ReactjstomscodingView Answer on Stackoverflow
Solution 26 - Reactjstw_hoffView Answer on Stackoverflow
Solution 27 - ReactjsJorcheView Answer on Stackoverflow
Solution 28 - ReactjsVaibhav SinghView Answer on Stackoverflow
Solution 29 - ReactjsNicoView Answer on Stackoverflow
Solution 30 - Reactjsshubhang shuklaView Answer on Stackoverflow
Solution 31 - ReactjsHanly NadackalView Answer on Stackoverflow
Solution 32 - ReactjsSourabh ChavanView Answer on Stackoverflow
Solution 33 - Reactjstbger99View Answer on Stackoverflow
Solution 34 - ReactjsoarkonView Answer on Stackoverflow