React router redirect outside of route component - javascript

I use React Router in my React application.
In Header component that isn't inside Router component i want to redirect user after register a form, but because Header component is outside of Router component i can't use this.props.history.push('/');.
How can i redirect user in Header component?
This is my App component:
<div>
<Header order={this.order}/>
<Router data={this.state.data}>
<div>
<Menu data={this.state.data}/>
<Route exact path="/" component={Home} />
<Route exact path="/post" component={PostList} />
<Route path="/showpost/:slug" component={ShowPost} />
<Route path="/page/:slug" component={ShowPage} />
<Route path="/login" component={Login} />
<Route path="/register" component={Register} />
<Route path="/forgotpassword" component={Forgot} />
<Route path="/password/reset/:token" component={Reset} />
<Route path="/logout" component={Logout} />
<Route path="/user" component={User} />
<Route path="/saveorder" render={()=><SaveOrder data={this.state.data}/>} />
</div>
</Router>
<Map />
<Footer />
</div>

You can use this.props.history.push('/') if your Header component is passed to the withRouter HOC.
withRouter allows you to get history in component props.
So... in Header component you should import withRouter HOC
import { withRouter } from 'react-router-dom';
and export your Header component like this:
export default withRouter(Header);
You can find more info about programmatic navigation here https://tylermcginnis.com/react-router-programmatically-navigate/
an example of what you want to do is found at the end of the post :)

move Header inside Router, only the component that are inside <Router> that can use any of react-router's apis.
the code would look like this:
<div>
<Router data={this.state.data}>
<div>
<Header order={this.order} />
<Menu data={this.state.data} />
<Route exact path="/" component={Home} />
<Route exact path="/post" component={PostList} />
<Route path="/showpost/:slug" component={ShowPost} />
<Route path="/page/:slug" component={ShowPage} />
<Route path="/login" component={Login} />
<Route path="/register" component={Register} />
<Route path="/forgotpassword" component={Forgot} />
<Route path="/password/reset/:token" component={Reset} />
<Route path="/logout" component={Logout} />
<Route path="/user" component={User} />
<Route
path="/saveorder"
render={() => <SaveOrder data={this.state.data} />}
/>
</div>
</Router>
<Map />
<Footer />
</div>

Related

How to have react load Home page and then route to others

I have a basic portfolio app that has the following structure:
App.js
function App() {
return (
<BrowserRouter>
<LeftNav />
<RightNav />
<NavBar />
<Switch>
<Route component={Home} path='/' exact />
<Route component={About} path='/about' />
<Route component={Project} path='/projects' />
<Route component={Contact} path='/contact' />
</Switch>
</BrowserRouter>
)
}
When I click on the link to go the production site it only renders the LeftNav, RightNav, and Navbar. I have to click on the Home component to have the Home Screen load.
I then tried putting the Home component outside of to look like:
function App() {
return (
<BrowserRouter>
<LeftNav />
<RightNav />
<NavBar />
<Home />
<Switch>
<Route component={Home} path='/' exact />
<Route component={About} path='/about' />
<Route component={Project} path='/projects' />
<Route component={Contact} path='/contact' />
</Switch>
</BrowserRouter>
)
}
This is the action I want upon clicking on the link, however then my components don't load. How do I structure this so that the Home component loads up on the initial click and that I'm able to navigate to other pages?
Your first version is good, just add a redirect and change the home path
import React from 'react';
import {BrowserRouter, Switch, Route, Redirect} from 'react-router-dom'; // import Redirect
function App() {
return (
<BrowserRouter>
<LeftNav />
<RightNav />
<NavBar />
<Switch>
<Route component={Home} path='/home' exact /> // change the path
<Route component={About} path='/about' />
<Route component={Project} path='/projects' />
<Route component={Contact} path='/contact' />
<Route path="/" exact> // Add the redirect
<Redirect to="/home" />
</Route>
</Switch>
</BrowserRouter>
)
}
You will have to exchange your home path from being the default page:
<Route component={Home} path='/' exact />
to
<Route component={Home} path='/home' exact />
and then add a 'Redirect' to your App.js :
<Route path="/" exact>
<Redirect to="/home" />
</Route>

React router always display at the bottom the Error page

I'm having a problem regarding using of error page in my react app. The 404 page always shows at the bottom of every page that I render. I'm new to react. I hope someone can help me.
This is my App.js
import {BrowserRouter as Router,Switch,Route} from 'react-router-dom';
import Login from './components/auth/Login';
import Register from './components/auth/Register';
import ErrorPage from './components/ErrorPage';
import Order from './components/Order';
import Navbar from './components/partials/Navbar';
import Footer from './components/partials/Footer';
import Shop from './components/Shop';
import ItemDetails from './components/ItemDetails';
import Cart from './components/Cart';
import Customize from './components/Customize';
const App = () => {
return (
<>
<Router>
<Switch>
<Route exact path='/login'>
<Login />
</Route>
<Route exact path='/register'>
<Register />
</Route>
<div>
<Navbar />
<Route exact path='/'>
<Shop />
</Route>
<Route exact path='/order'>
<Order />
</Route>
<Route exact path='/item/details'>
<ItemDetails />
</Route>
<Route exact path='/cart'>
<Cart />
</Route>
<Route exact path='/customize'>
<Customize />
</Route>
<Route component={ErrorPage} />
</div>
</Switch>
</Router>
<Footer />
</>
);
}
export default App;
I searched about handling error page in react and I see that the order of routes is important but I don't get why I'm still getting the error page even it's in the bottom. Thank you guys.
That's because the switch component returns the first child at the root that meets the path condition. If the path condition doesn't exist it's evaluated as true. In your case you have 3 child Login, Register and the div which will always be evaluated to true. So just move all routes to the root of your switch:
<Router>
<Switch>
<Route exact path='/login'>
<Login />
</Route>
<Route exact path='/register'>
<Register />
</Route>
<div>
<Navbar />
<Switch>
<Route exact path='/'>
<Shop />
</Route>
<Route exact path='/order'>
<Order />
</Route>
<Route exact path='/item/details'>
<ItemDetails />
</Route>
<Route exact path='/cart'>
<Cart />
</Route>
<Route exact path='/customize'>
<Customize />
</Route>
<Route component={ErrorPage} />
</Switch>
</div>
</Switch>
</Router>

Hide specific components for a route using React Router

In my code, I want Header & Footer components to be rendered in all routes except '/login'so how to do that? How to hide component on a specific route?
const AppRouter = () => {
return (
<BrowserRouter>
<div>
<Header />
<Switch>
<Route path="/login" component={Login} /> {/* I wanna render this route without Header & Footer */}
<Route path="/" component={Home} exact />
<Route path="/product" component={ProductOverview} />
<Route path="/profile" component={Profile} />
<Route component={NotFound} />
</Switch>
<Footer />
</div>
</BrowserRouter>
);
};

route redirects to nothing react-router 4 [duplicate]

This question already has answers here:
Route is not matched
(3 answers)
Closed 5 years ago.
I'm not sure why everything is redirecting to a blank page:
I'm using:
"react-router": "^4.2.0",
"react-router-dom": "^4.1.1",
App.js
import { BrowserRouter, Route, Switch } from 'react-router-dom';
class Container extends Component{
render() {
return (
<div>{this.props.children}</div>
);
}
}
export default class App extends Component {
render() {
return (
<BrowserRouter onUpdate={onUpdate}>
<Switch>
<Route component={HomePageContainer} exact path="/" />
<Route component={CompanyDetailContainer} name="companydetail" path="interviews/companies/:companyId/details" />
<Route component={InterviewContainer} name="interview" path="interviews/companies/:companyId" />
<Route component={Container} path="/" />
<Route component={NotFound} path="*" />
</Switch>
</BrowserRouter>
);
}
}
Homepage route to '/' is working fine.
What's not working are all the other routes.
For example when a user clicks a hyperlink that redirects to these routes or other routes other than the default route, I'm getting a blank page:
<Route component={CompanyDetailContainer} name="companydetail" path="interviews/companies/:companyId/details" />
<Route component={InterviewContainer} name="interview" path="interviews/companies/:companyId" />
Here is how my routes were working when I was using react-router v3:
<Router history={browserHistory} onUpdate={onUpdate}>
<Route path="/">
<IndexRoute component={HomePageContainer} />
<Route component={InterviewContainer} name="interview" path="interviews/companies/:companyId" />
<Route component={About} name="about" path="about" />
<Route component={JobList} name="jobs" path="jobs" />
</Route>
<Route component={Container} path="/" />
<Route component={NotFound} path="*" />
</Router>
Note that I also added the new route for companydetail just recently.
All your paths needs to be with respect to to base path i.e. /
Change your router config to
<Switch>
<Route component={HomePageContainer} exact path="/" />
<Route component={CompanyDetailContainer} name="companydetail" path="/interviews/companies/:companyId/details" />
<Route component={InterviewContainer} name="interview" path="/interviews/companies/:companyId" />
<Route component={Container} path="/" />
<Route component={NotFound} path="*" />
</Switch>
Try wrapping your router in an anonymous function.
const App = () => (
<BrowserRouter onUpdate={onUpdate}>
<Switch>
<Route component={HomePageContainer} exact path="/" />
<Route component={CompanyDetailContainer} name="companydetail" path="interviews/companies/:companyId/details" />
<Route component={InterviewContainer} name="interview" path="interviews/companies/:companyId" />
<Route component={Container} path="/" />
<Route component={NotFound} path="*" />
</Switch>
</BrowserRouter>
)

Default component in nested routes in React Router

In React Router I have a nested Route
<Route path='about' component={{main: About, header: Header}}>
<Route path='team' component={Team} />
</Route>
So now it shows Team when I go to /about/team.
But how do I set which Component to be seen when I visit /about?
I have tried
<Route path='about' component={{main: About, header: Header}}>
<IndexRoute component={AboutIndex} />
<Route path='team' component={Team} />
</Route>
and
<Route path='about' component={{main: About, header: Header}}>
<Route path='/' component={AboutIndex} />
<Route path='team' component={Team} />
</Route>
but it doesn't work.
My About component looks like this
class About extends React.Component {
render () {
return (
<div>
<div className='row'>
<div className='col-md-9'>
{this.props.children}
</div>
<div className='col-md-3'>
<ul className='nav nav-pills nav-stacked'>
<li className='nav-item'><IndexLink className='nav-link' to='/about' activeClassName='active'>About</IndexLink></li>
<li className='nav-item'><Link className='nav-link' to='/about/team'>Team</Link></li>
</ul>
</div>
</div>
</div>
);
}
}
REACT ROUTER 4 UPDATE
The default route is the one without a path.
import BrowserRouter from 'react-router-dom/BrowserRouter';
import Switch from 'react-router-dom/Switch';
import Route from 'react-router-dom/Route';
<BrowserRouter>
<Switch>
<Route exact path='/about' component={AboutIndex} />
<Route component={AboutIndex} /> // <--- don't add a path for a default route
</Switch>
</BrowserRouter>
If you don't need this object {main: About, header: Header} in your component, then just put AboutIndex in the component attribute. That should work
<Router history={browserHistory}>
<Route path='about' component={AboutIndex}>
<IndexRoute component={AboutIndex} />
<Route path='team' component={Team} />
</Route>
</Router>
If you still need main and header components, just add them in as either parent, child, or sibling components depending on your needs
React Router v6
The route has an attribute index which is used to define the index route as per the docs.
<Route index element={<DefaultPage />} />
Another way to do I found is to use the Navigate component of the react-router-dom package with the index attribute. After the a user navigates to the support route, it will default to the about page in the following example.
<Route path="support/*" element={<Support />}>
<Route index element={<Navigate to="about" replace />} />
<Route path="about" element={<About />} />
<Route path="contact" element={<Contact/>} />
</Route>

Categories

Resources