React nested route render the parent component with the child component - javascript

I am learning about React (Coming from ASP.NET). When I go to '/employee' it will display employee list table. But when I go to '/employee/create' it will display both the table and the create form. How to display only create employee form when I to '/employee/create' ?
export default class App extends Component {
static displayName = App.name;
render() {
return (
<Layout>
<Route exact path='/' component={Home} />
<Route path='/counter' component={Counter} />
<AuthorizeRoute path='/fetch-data' component={FetchData} />
<Route exact path='/employee' component={EmployeeIndex} />
<Route path='/employee/create' component={EmployeeCreate} />
<Route path='/employee/details/:id' component={EmployeeDetails} />
</Layout>
);
}
}

To do that, you will need to add a <Switch> around your Routes:
import { Route, Switch } from "react-router";
<Switch>
<Route exact path='/' component={Home} />
<Route path='/counter' component={Counter} />
<AuthorizeRoute path='/fetch-data' component={FetchData} />
<Route exact path='/employee' component={EmployeeIndex} />
<Route path='/employee/create' component={EmployeeCreate} />
<Route path='/employee/details/:id' component={EmployeeDetails} />
</Switch>
It works just like a normal `switch-case, will only render the first matching path within your Routes.
Without <Switch> it will render ALL matching routes.

Here what I use in my apps.
Make separate components for all pages and import in App.js under src. Make use of state and props to store the data and create ID. Install npm i react-router-dom to access react route.
import { Switch, Route, Redirect } from "react-router-dom";
<Switch>
<Route exact path="/" component={Home} />
<Route exact path="/employee" component={Employee} />
<Route exact path="/createEmployee" component={Create} />
<Route exact path="/employeeDetails" component={Details} />
<Redirect to = "/" />
</Switch>
for homepage - Home.js
for employee list table - Employee.js
create employee - Create.js
go to employee's detail - Details.js
Redirect to - will redirect to homepage if exact URL is not entered.

Related

React Router Dom, show Header component only for some pages [duplicate]

This question already has answers here:
How do I render components with different layouts/elements using react-router-dom v6
(2 answers)
Closed 8 months ago.
Header will appear in all components except ConfirmEmail. Basically I don't want the Header to appear when the ConfirmEmail component is opened. What should I do?
Router setup:
import React from 'react';
import {BrowserRouter,Routes ,Route} from 'react-router-dom'
import Header from "../Components/Header";
import 'bootstrap/dist/css/bootstrap.min.css';
import 'bootstrap/dist/js/bootstrap.bundle.min.js';
import Home from '../Components/Home';
import Contact from '../Components/Contact';
import Login from '../Components/Login';
import Register from '../Components/Register';
import ConfirmEmail from '../Components/SuccessEmailApproved';
const App = () =>{
return(
<BrowserRouter>
<Header/>// If confirmEmail component is opened, hide it here
<Routes>
<Route path="/" element={<Home/>} />
<Route path="/home" element={<Home/>} />
<Route path="/ev" element={<Home/>} />
<Route path="/contact" element={<Contact/>} />
<Route path="/iletisim" element={<Contact/>} />
<Route path="/login" element={<Login/>} />
<Route path="/giris" element={<Login/>} />
<Route path="/register" element={<Register/>} />
<Route path="/kayit" element={<Register/>} />
<Route path="/ConfirmEmail" element={<ConfirmEmail />} /> //I don't want the header component to appear if this is opened. but it will appear in other components.
</Routes>
</BrowserRouter>
);
}
export default App;
Update:
Tried the below solution and it's working, but is there a better way?
{window.location.pathname !== "/ConfirmEmail" ?<Header/>:<></>}
You could create a Layout.js component like below. It's kind of the common way to set up the same structure for multiple pages in React Router Dom v6.
import { Outlet } from "react-router-dom";
import Header from "../Header"; // ⚠️ verify it's the correct path
const Layout = () => {
return (
<>
<Header />
<Outlet />
</>
);
};
export default Layout;
And change App as below. Notice ConfirmEmail page is left out from the pages where you want Header:
// ⚠️ previous imports
import Layout from "./components/Layout"; // ⚠️ verify it's the correct path
const App = () =>{
return(
<BrowserRouter>
<Routes>
<Route element={<Layout />}>
<Route path="/" element={<Home/>} />
<Route path="/home" element={<Home/>} />
<Route path="/ev" element={<Home/>} />
<Route path="/contact" element={<Contact/>} />
<Route path="/iletisim" element={<Contact/>} />
<Route path="/login" element={<Login/>} />
<Route path="/giris" element={<Login/>} />
<Route path="/register" element={<Register/>} />
<Route path="/kayit" element={<Register/>} />
</Route>
<Route path="/ConfirmEmail" element={<ConfirmEmail />} />
</Routes>
</BrowserRouter>
);
}
export default App;
You can have as many layouts as you want (MainLayout, AuthLayout, Layout...). The setup is the same, an Outlet and a Route that has your Layout as element and wraps the pages for that Layout.

Reactjs private route always take me on first route after page refresh

I am new on reactjs and stuck in a scenario like when I login the application using credentials and lands on the dashboard page, after when I navigate to some other page like List page from dashboard and try to refresh the page on list page it take me back to dashboard page instead to stay on the current page i.e List page.
Below is the Route Page of my code.
<BrowserRouter>
<Switch>
<Route exact path="/login" component={Login} />
<Route exact path="/forgotPassword" component={ForgotPassword} />
<Route exact path="/changePassword" component={ChangePassword} />
<PrivateRoutes exact path="/" component={Dashboard} />
<PrivateRoutes exact path="/list" component={List} />
<PrivateRoutes exact path="/listDetails/:id" component={ListDetails} />
</Switch>
</BrowserRouter>
And Private route code is
class PrivateRoute extends Component {
render() {
let componentData = '';
componentData = <div><SideNavigation /> <Route render={() => <this.props.component {...this.props} />} /> </div>;
return componentData;
}
}

How to hide/show a component inside another component in ReactJS

I have my application looking something like below..
import FirstComponent from "./components/firstComponent";
import NextComponent from "./components/nextComponent";
import MyProgressComponent from "./components/progressComponent";
class App extends React.Component {
render() {
return (
<Router>
<div>
<MyProgressComponent />
<Route path="/" exact component={FirstComponent} />
<Route path="/nextComponent" component={NextComponent} />
</div>
</Router>
);
}
}
As we can see 'MyProgressComponent' is visible when we navigate between 'http://localhost:3000/' and 'http://localhost:3000/nextComponent' because it is directly nested under Router component in App component. But I want 'MyProgressComponent' to be visible only in 'http://localhost:3000/nextComponent' and hidden in 'http://localhost:3000/'. Any suggestion ?
I can do this by importing 'MyProgressComponent' inside each component wherever required but I don't want to duplicate it in each component.
You can render multiple components using the below syntax
<Route path="/nextComponent" render={() =>
<>
<MyProgressComponent />
<NextComponent />
</>
}
/>
Based on #Crocsx comment you can apply following check on your code.
<Router>
<div>
{this.props.location.pathname === "/nextComponent" ? <MyProgressComponent />: null}
<Route path="/" exact component={FirstComponent} />
<Route path="/nextComponent" component={NextComponent} />
</div>
</Router>
you can use switch provided by router to achieve this.
Something like below should work for you.
<Switch>
<Route exact path="/nextComponent" component={MyProgressComponent} />
</Switch>
<Switch>
<Route path="/" exact component={FirstComponent} />
<Route path="/nextComponent" component={NextComponent} />
</Switch>
more documentation is available here https://reacttraining.com/react-router/web/guides/basic-components

How do you route within a route in react

I'm new to react and trying to get this whole routing thing down. I have page which I want to render multiple routes withing.
My main index.js file looks like this:
ReactDOM.render(
<BrowserRouter>
<div>
<Switch>
<Route path="/adminDash" exact component={AdminDashMain}/>
<Route path="/admin/ClientSearch" exact component={ClientDetailsMain}/>
<Route path="/" exact component={LogIn}/>
</Switch>
</div>
</BrowserRouter>
, document.getElementById('root'));
in client search main I have 3 components
class ClientDetailMain extends React.Component {
render() {
return(
<div>
<Header />
<SubHeader username={this.props.match.params.username} />
<Display username={this.props.match.params.username}/>
</div>
);
}
}
export default withRouter(ClientDetailMain);
I'm using <Display/> as a container and inside of that I want to have other route so that a person can go to
/admin/ClientSearch/refined
/admin/ClientSearch/general
/admin/ClientSearch/fixed
I figured out that the /admin/ClientSearch will match regardless so the header and subheader show on all 3 routes, however my routes which are written as:
const Display = () =>{
return(
<div>
<Route path ='/admin/ClientSearch/refined' component={<Refined/>
<Route path ='/admin/ClientSearch/general' component={<General/>
<Route path ='/admin/ClientSearch/fixed' component={<Fixed/>
</div>
)
};
export default withRouter(ClientDisplay);
aren't displaying anything. Is this how I should be writing it? When I link to and of those 3 the header and subheader show up but the components in the individuals routes don't.
For example
'/admin/ClientSearch/fixed' shows the header and subheader but none of its own components.
They key is in the "exact" attribute of your Routes. In addition, when you create a component that has routes inside, you can get the url of the previous routes through it's props. Like this example:
class Main extends React.Component {
render(){
return (
<Switch>
<Route exact path='/' component={Home} />
<Route exact path='/about' component={About} />
<Route exact path='/contact' component={Contact} />
<Route path='/admin' component={AdminArea} />
</Switch>
)
}
}
Then you have your sub-routes like this:
const AdminArea = ({match}) => (
<Switch>
<Route exact path={`${match.url}/specie`} component={Component} />
<Route exact path={`${match.url}/color`} component={Component} />
<Route exact path={`${match.url}/user/:id`} component={Component}/>
</Switch>
)

404 page in REACT

I created the component NotFound and it works fine when I go to a page that doesn't exist. But the same page it's appearing in all my pages, not only the one that doesn't exist. This is the component:
import React from 'react'
const NotFound = () =>
<div>
<h3>404 page not found</h3>
<p>We are sorry but the page you are looking for does not exist.</p>
</div>
export default NotFound
And this is how I used it in the main page:
class MainSite extends Component {
render () {
return (
<div>
{/* Render nav */}
<Route path='/dashboard' component={Nav} />
<Route path='/retrospectives' component={Nav} />
<Route path='/users' component={Nav} />
<Route path='/projects' component={Nav} />
{/* Dashboard page */}
<ProtectedRoute exact path='/dashboard' component={DashboardPage} />
{/* Retrospectives page */}
<ProtectedRoute exact path='/retrospectives' component={RetrospectivesPage} />
{/* Users page */}
<ProtectedRoute exact path='/users' component={UsersPage} />
{/* Projects page */}
<ProtectedRoute exact path='/projects' component={ProjectsPage} />
{/* Retrospective related pages */}
<Route exact path='/retrospectives/:retrospectiveId' component={Retrospective} />
<Route exact path='/join-retrospective' component={JoinRetrospective} />
<ProtectedRoute exact path='/create-retrospective/:retrospectiveId' component={Retrospective} />
{/* OnBoarding pages */}
<ProtectedRoute exact path='/beta-code' component={BetaCodeAccess} />
<Route exact path='/auth-handler' component={AuthHandler} />
<Route exact path='/join-organization' component={JoinOrganization} />
</div>
)
}
}
export default MainSite
As you can see I use <Route path="*" component={NotFound} /> to create the 404 pages, but that component is appearing in every existing page as well. How can I fix this?
Try this one:
import { Switch, Route } from 'react-router-dom';
<Switch>
<Route path='/dashboard' component={Nav} />
<Route path='/retrospectives' component={Nav} />
<Route path='/users' component={Nav} />
<Route path='/projects' component={Nav} />
<Route path="" component={NotFound} />
</Switch>
All below example works fine:
<Route path="" component={NotFound} /> // empty ""
<Route path="*" component={NotFound} /> // star *
<Route component={NotFound} /> // without path
Or if you want to return a simple 404 message without any component:
<Route component={() => (<div>404 Not found </div>)} />
For those who are looking for an answer using react-router-dom v6, many things had changed. Switch for example doesn't exists anymore, you have to use element instead of component, ... Check this little example to get you an idea:
import React from 'react'
import ReactDOM from 'react-dom'
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'
import './index.css'
import App from './App'
const Test = () => (
<h1>404</h1>
)
ReactDOM.render(
<React.StrictMode>
<Router>
<Routes>
<Route path='/' element={<App />} />
<Route path='*' element={<Test />}/>
</Routes>
</Router>
</React.StrictMode>,
document.getElementById('root')
)
With this you are defining your home route and all the other routes will show 404. Check the official guide for more info.
Try This:
import React from "react";
import { Redirect, Route, Switch, BrowserRouter } from 'react-router-dom';
import HomePage from './pages/HomePage.jsx';
import NotFoundPage from './NotFoundPage.jsx';
class App extends React.Component {
render(){
return(
<BrowserRouter>
<Switch>
<Route exact path='/' component={HomePage} />
<Route path="*" component={NotFoundPage} />
</Switch>
</BrowserRouter>
)
}
}
export default App;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
Simply import Switch from react-router-dom and wrap all your Routes in the Switch Component. Also Important here is to note to keep your 404Page component at the very bottom(just before your switch ending tag) This way it will match each component with its route first. If it matches, it will render the component or else check the next one. Ultimately if none matching routes will be founded, it will render 404Page
react router is a headache for new coders. Use this code format. This is class component but you can make a functional component and use it.
import React from "react";
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
import HomePage from './pages/HomePage.jsx';
import NotFoundPage from './NotFoundPage.jsx';
import Footer from './Footer';
class App extends React.Component {
render(){
return(
<Router>
<Routes>
<Route exact path='/' element={HomePage} />
<Route path="*" element={NotFoundPage} />
</Routes>
<Routes>
<Route path="/" element={Footer}/>
</Routes>
</Router>
)
}
}
export default App;

Categories