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?
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.
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.
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.
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.
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
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>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With