Reputation: 6909
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
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
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