Coding Duchess
Coding Duchess

Reputation: 6909

<BrowserRouter> ignores the history prop

I was using the following code from an online course for React routing:

import { Router, Route, browserHistory } from 'react-router';

ReactDOM.render(
  <Router history={browserHistory}>
     <Route path="/" component={App></Route>
     <Route path="/One" component={One}></Route>

     <Route path="/Two" component={Two}></Route>
  </Router>, document.getElementById('root'));

It gave me a following error 'react-router' does not contain an export named 'browserHistory'.

I did some research and found that I was using React Router v4, and the above code was for v3, so i found that I should be using <BrowserRouter> instead of <Router> so I changed my code to:

import { BrowserRouter, Route, Switch } from 'react-router-dom';

ReactDOM.render(
   <BrowserRouter history={History}>

     <div> 
    <Route path="/" component={App}></Route>

    <Route path="/One" component={One}></Route>

    <Route path="/Two" component={Two}></Route>


    <Route path="*" component={NoMatch}></Route>

  </div></BrowserRouter>, document.getElementById('root'));

History I have in a separate file:

import { createBrowserHistory } from 'history'

export default createBrowserHistory();

Now the page loads without an error but if I use Developer tools, I can see a warning:

Warning: <BrowserRouter> ignores the history prop. To use a custom history, use `import { Router }` instead of `import { BrowserRouter as Router }`."

Another issue is that <Route path="*" component="NoMatch}></Route> only supposed to load NoMatch component when no path specified in the router but it loads on every page, regardless. Can anyone help figure out how can I fix the issues?

Upvotes: 11

Views: 28814

Answers (2)

andrewgi
andrewgi

Reputation: 632

You can only use history with <Router> hence the error message. See the API on the sidebar in react-router docs.

Browser Router

<BrowserRouter>
 basename: string
 getUserConfirmation: func
 forceRefresh: bool
 keyLength: number
 children: node

Router

<Router>
 history: object
 children: node

https://reacttraining.com/react-router/web/api/Router/history-object

As for the no match, you need a switch and to put the last component without a path. Right now you are grabbing every route with path="*"

Again, see docs https://reacttraining.com/react-router/web/example/no-match

<Switch>
  <Route path="/" exact component={Home}/>
  <Redirect from="/old-match" to="/will-match"/>
  <Route path="/will-match" component={WillMatch}/>
  <Route component={NoMatch}/>
</Switch>

Upvotes: 2

Aaqib
Aaqib

Reputation: 10350

I am assuming you are using react-router v4

Firstly, Instead of <BrowserRouter> make use of <Router>

import { Router } from 'react-router-dom';

You can get access to the history object's properties by using <withRouter> as mentioned Here

Export the component using <withRouter> , something like :

import React, { Component } from 'react';
import { withRouter } from 'react-router-dom';

class SomeComponent extends Component {
render() {}
}
export default withRouter(SomeComponent);

Secondly , you can make use of <Switch> as it renders the first child <Route> or <Redirect> that matches the location

And you can wrap a <Switch> in a <div> like this:

   <Router>
      <div> 
        <Switch>
         <Route path="/" component={App}></Route>
         <Route path="/One" component={One}></Route>
         <Route path="/Two" component={Two}></Route>
         <Route component={NoMatch}></Route>
        </Switch>
      </div>
   </Router>

NOTE : Last Route doesn't have path="*"

You can read more about <Switch> on a ReactTraining Github

If you want to read more about React Router V4 or <withRouter> , You can read on this Medium Article

Upvotes: 11

Related Questions