Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 360
Coding Duchess Avatar asked Jan 19 '18 20:01

Coding Duchess


People also ask

What is the difference between BrowserRouter and Router?

The main difference between the two is the way they store the URL and communicate with your web server. A <BrowserRouter> uses regular URL paths.

When should I use BrowserRouter and Router?

This router uses the HTML 5 History API to keep the UI in sync with the the path. BrowserRouter is used for doing client side routing with URL segments. You can load a top level component for each route. This helps separate concerns in your app and makes the logic/data flow more clear.

How do I push history into my React Dom Router?

push() Method. history. push() is another approach where we make use of the history props React Router provides while rendering a component. In other words, this works when the component is being rendered by React Router, bypassing the component as a Component prop to a Route.

What is the BrowserRouter /> component?

BrowserRouter: BrowserRouter is a router implementation that uses the HTML5 history API(pushState, replaceState and the popstate event) to keep your UI in sync with the URL. It is the parent component that is used to store all of the other components.


2 Answers

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

like image 118
Aaqib Avatar answered Oct 27 '22 00:10

Aaqib


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>
like image 35
andrewgi Avatar answered Oct 27 '22 00:10

andrewgi