<BrowserRouter> ignores the history prop - javascript

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?

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>

Related

Matched leaf route at location "/" does not have an element

Matched leaf route at location "/" does not have an element. This means it will render an with a null value by default resulting in an "empty" page
//App.js File
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import Home from './pages/Home';
// import ReactDOM from "react-dom";
const App = () => {
return (
<Router >
<Routes>
<Route path="/" component={ Home }></Route>
</Routes>
</Router>
)
}
export default App;
**My any react router related code not working i don't know why it happend when i start insert some route in program so it show this error **
In V6, you can't use the component prop anymore. It was replaced in favor of element:
<Route path="/" element={<Home />}></Route>
More info in the migration doc.
I had the same problem. Replace component with element and it worked.
Replace this:
<Route path="/" component={HomePage} exact />
with this:
<Route path="/" element={<HomePage/>} exact />
I had the same error however my fix was slightly different
I had spelled element wrong.
<Route exact path='/MyGames' elemtent={<MyGames/>}/>
and this was the error it gave me in the browser console
Matched leaf route at location "/MyGames" does not have an element. This means it will render an <Outlet /> with a null value by default resulting in an "empty" page.
Very simple:
use element instead of component
wrap the your component like this: {<Home/>} instead of {Home}
<Route path="/" component={ <Home/> } />
in version 6:
component replaced with element and needs to close "</Route>"
<Route exact path="/" element={<AddTutorial />}></Route>
https://reactrouter.com/docs/en/v6/getting-started/overview
This is a common problem if you are using react-router-dom V6
To solve this it's simple
In your code
Replace component with element
Replace {home} with {}
This becomes...
<Route path="/" element={}>
This will definitely solve the problem.
If you're using react-router-dom 6 or above, you may have a routes array that includes parent and child routes. You may then try to open a route such as
/portal
and get this error because that component corresponds to a child route
/:customerid/portal
but you haven't read your routes (and their child routes) closely enough to see that.

How to use Memory Route In React Js ? What is exact method to use route?

I have made use of react js memory router as below in my App.js -
import logo from './logo.svg';
import './App.css';
import './Components/Login'
import Login from './Components/Login';
import {useSelector} from 'react-redux';
import { useEffect } from 'react';
import Welcome from './Components/Welcome';
import{MemoryRouter as Router, Route, Switch} from 'react-router-dom'
function App() {
const state = useSelector(state => state.allReducers)
console.log(state.user.isValid);
return (
<Router>
<Switch>
<Route exact="/" component={Login}></Route>
<Route exact="/" component={Welcome}></Route>
</Switch>
<div className="App">
{state.user.isValid==false ||state.user.isValid== undefined ? <Login></Login> : <Welcome name={state.user.userName}></Welcome>}
</div>
</Router>
);
}
export default App;
But this is displaying my Login component twice on the screen.
How can I avoid this?
Your route configs should be:
<Switch>
<Route path="/login" component={Login} />
<Route path="/" component={Welcome} exact={true} />
</Switch>
exact should be a boolean value. And it'll tell the router only render the route match exactly with the URL. It means, the router only renders the Welcome component when the user stays at /.
But after you changed to my suggestion, you still see 2 login forms if you navigate to /login. Because the div.app will be rendered for every route :D
You're using the same route for both components: <Route exact="/"... so React will show you both. Use different routes for each component. And your syntax is a bit wrong. Like this:
<Switch>
<Route exact path="/"><Welcome /></Route>
<Route exact path="/login"><Login /></Route>
</Switch>

Receive single React element child in console

I am trying to do a basic router with history, I have:
import {BrowserRouter, Route} from 'react-router-dom';
import createBrowserHistory from 'history/createBrowserHistory'
...
render() {
return (
<BrowserRouter>
<Switch>
<Route path="/login" component={PageA}/>
<Route path="/dashboard" component={PageB}/>
<Route path="/companies" component={PageC}/>
</Switch>
</BrowserRouter>
)
}
}
ReactDOM.render(<App />, document.getElementById('app'))
But I keep getting:
Uncaught Error: React.Children.only expected to receive a single React element child
The error is repeated four times in console.
I have followed a number of other answers on forums but it still doesn't work.
What is wrong with this?
To keep things clean:
You should create a history.js in the src like so:
import createHistory from 'history/createBrowserHistory';
export default createHistory();
In your index.js import Router not BrowserRouter and pass the history as a prop like so:
import {Router, Route, Switch} from 'react-router-dom';
import history from '../history' // relative path to the file you created above...
...
render() {
return (
<Router history={history}> // pass it as a prop here...
<Switch>
<Route path="/login" component={PageA}/>
<Route path="/dashboard" component={PageB}/>
<Route path="/companies" component={PageC}/>
</Switch>
</Router>
)
}
}
Now you can use history.push('/path_you_want') to redirect after an action etc...
Side-Note: This is probably overkill if you're not using redux... For simpler redirects look into the <Redirect /> component offered by the library... more info with examples: https://reacttraining.com/react-router/web/api/Redirect

Router.match is not been called on every route change

I have server side rendering app and using react-router for routing. I was using Router.Run Before as the method is no more I am using Router.Match.Previously when there was route change router.run used to be called but same behavior is not happening in the router.match. Is there any reason behind it?
I have defined my router in entry module defined below and it will go to Layout component to look for route paths:
import { Router, Route, IndexRoute, hashHistory } from "react-router";
ReactDOM.render(
<Router history={hashHistory}>
<Route path="/" component={Layout}>
//<IndexRoute component={Featured}></IndexRoute>
<Route path="archives" name="archives" component={Archives}></Route>
<Route path="settings" component={Settings}></Route>
<Route path="featured" component={Featured}></Route>
</Route>
</Router>,
document.getElementById('app'));
Layout component will bind the path defined in router to different components in Layout Component
import { Link } from "react-router";
class Layout extends React.Component(
render(){
return(
{this.props.children}
<li><MenuItem><Link to="archives">archives</Link></MenuItem></li>
<li><MenuItem><Link to="settings">settings</Link></MenuItem></li>
<li><MenuItem><Link to="featured">featured</Link></MenuItem></li>
)
}
);
You can define any action for your route components.its working fine for me

Root folder of my React application conflicts with React-Router

My React application is hosted at www.mywebsite.com/myreact
When I defined my routes, I've done something like this:
<Router history={history}>
<Route path="/" component={App} />
<Route path="login" component={Login} />
</Route>
</Router>
Although, it keeps complaining that /myreact is not defined in the route.
When I define it, that way:
<Route path="/myreact" component={App} />
and I try to access the URL www.mywebsite.com/myreact/login, the browser throw a 404 error.
But I can access www.mywebsite.com/myreact properly though.
What should I do?
Thanks.
You should be able to create a custom history object with a different basename for your apps 'root' url. with the useRouterHistory enhancement when creating the history object
https://github.com/reactjs/react-router/blob/master/docs/API.md#userouterhistorycreatehistory
some relavent comments in this github issue thread
import { createHistory } from 'history';
import { useRouterHistory } from 'react-router';
const browserHistory = useRouterHistory(createHistory)({
basename: '/myreact'
});
your routes files should now work using browserHistory
<Router history={browserHistory}>
<Route path="/" component={App} />
<Route path="login" component={Login} />
</Route>
</Router>

Categories