How to render component inside a component based on route - javascript

I have routes like this:
<Provider store={store}>
<BrowserRouter>
<Route path="/" component={App} />
<Route path="/customers" component={Customers} />
<Route path="/tickets" component={Tickets} />
</BrowserRouter>
</Provider>
When the route is /customers I want Customers component inside App component. When the route is /tickets I want Tickets inside App and not Customers. I could check the route using
this.props.location.pathname == '/customers' but that's what the Router is for, right? I shouldn't be checking the route and rendering.
Based on my routes above, I see Customers component below App and not inside it.
The App consists of header and stuff. I don't want to add header code to all my components.
App.js:
<Header style={{ height: '39px', lineHeight: '39px' }}>
<Link to="/home">
<div className="logo" style={{ float: 'left' }}>
<img src="" />
<h2>Appnam</h2>
</div>
</Link>
{navEl}
</Header>
<Content >
// Customer or Tickets component here based on route
</Content>
How do I render the components inside App based on the route.

Assuming you have App as the main component, and you want the Tickets and Customers components inside the App component, you can make use of nested routes
<Provider store={store}>
<BrowserRouter>
<Route path="/" component={App} />
</BrowserRouter>
</Provider>
Inside App component
class App extends React.Component {
render() {
return (
<div>
{/* rest of App code */}
<Route path="/customers" component={Customers} />
<Route path="/tickets" component={Tickets} />
</div>
)
}
}

make use of.
<Provider store={store}>
<BrowserRouter>
<Route exact path="/" component={App} />
<Route exact path="/customers" component={Customers} />
<Route exact path="/tickets" component={Tickets} />
</BrowserRouter>
that will work

Related

Nested Routing not working in react-router version 6 [duplicate]

I was refactoring my React app after updating React Router to v6 and I got rid of the error I was getting in my routes, except now the desired layout is broken.
I need to include a permanent toolbar and a sidebar to be visible only in some pages. I tried to follow the docs but now the layout component is placed above all the pages it should be wrapping, not just overlapping them, but actually concealing them behind it.
The Layout component:
function Layout({ children }) {
return (
<div className="layout">
<Header />
<SidePanel />
<div className="main" style={{ marginTop: "100px" }}>
{children}
</div>
</div>
);
}
export default Layout;
The AppRouter component:
function AppRouter() {
return (
<Router>
<Routes>
<Route path="/" exact element={<Home />} />
<Route path="/login" element={<Login />} />
<Route path="/sign-up" element={<SignUp />} />
<Route element={<Layout />}>
<Route path="/diary" element={<Diary />} />
<Route path="/results" element={<Results />} />
<Route path="/details" element={<Details />} />
<Route path="/about" element={<About />} />
</Route>
</Routes>
</Router>
);
}
export default AppRouter;
Layout should render an Outlet for the children Routes to be rendered into.
import { Outlet } from 'react-router-dom';
function Layout() {
return (
<div className="layout">
<Header />
<SidePanel />
<div className="main" style={{ marginTop: "100px" }}>
<Outlet />
</div>
</div>
);
}
Outlet
An <Outlet> should be used in parent route elements to render their
child route elements. This allows nested UI to show up when child
routes are rendered.

ReactJS Routing Page Refresh

Currently using ReactJS to construct a small web app. I have the following parent function:
const Main = () => {
return (
<div className="dialog-base">
<BrowserRouter>
<Switch>
<Route exact path="/login" component={Login}></Route>
<Route exact path="/login/forgot_password" component={ForgotPwd}></Route>
<Route exact path="/login/reset_password/:key" component={ResetPwd}></Route>
<Route exact path="/portal" component={Portal}></Route>
</Switch>
</BrowserRouter>
</div>
);
}
and the following is the "Portal" component:
class Portal extends React.Component {
render = () => {
return (
<BrowserRouter basename="/main">
<div className="navmenu">
<NavLink to="messaging" activeClassName="selected">Messaging</NavLink>
<NavLink to="files" activeClassName="selected"></NavLink>
<NavLink to="payledger" activeClassName="selected"></NavLink>
</div>
<div className="apparea">
<Switch>
<Route path="/messaging" component={Messaging}></Route>
<Route path="/files" component={Files}></Route>
<Route path="/payledger" component={PayLedger}></Route>
</Switch>
</div>
</BrowserRouter>
);
}
}
When the portal component is loaded and I refresh the web page, the page goes blank. I am assuming that this has something to do with the nested routing? Any help on how to fix it would be much appreciated.
You don't need two <BrowserRouter />. Just define one <BrowserRouter /> in your top level component.
In react-router-dom v4+ the <Route /> is just like a regular component and you can use it inside your components to render UI when the path matches the URL.
Here is the working codesandbox example.
Make sure not to put exact on your parent <Route /> because when you have child routes like /main/messaging the <Route exact path="/main" /> never gets to render and therefore children of that route can't be rendered also.
You keep your <Main /> component as is but remove the exact from the <Route path='/portal' /> and change the <Portal />.
class Portal extends React.Component {
render = () => {
return (
<React.Fragment>
<div className="navmenu">
<NavLink to="/portal/messaging" activeClassName="selected">Messaging</NavLink>
<NavLink to="/portal/files" activeClassName="selected"></NavLink>
<NavLink to="/portal/payledger" activeClassName="selected"></NavLink>
</div>
<div className="apparea">
<Switch>
<Route path="/portal/messaging" component={Messaging}></Route>
<Route path="/portal/files" component={Files}></Route>
<Route path="/portal/payledger" component={PayLedger}></Route>
</Switch>
</div>
</React.Fragment>
);
}
}

Unable to render react components upon clicking the Links

I have a react application in which I have wrapped layout components for the other routes, the thing is when I click the links present in the sidebar(part of layout) they are not being rendered on the screen, here is my code.
App.js
//Imports here
<Provider store={store}>
<Router>
<Switch>
<Layout>
<Route exact path="/admin" render={() => <Admin />} />
<Route exact path="/employees" render={() => <Employees />} />
<Route exact path="/profile" component={Profile} />
</Layout>
<Switch>
</Router>
</Provider>
Layout.js
//imports here
//styling here
<Link to='/employees' />
// and likewise for rest of the routes
When clicking the links ie, employees or profile they aren't being rendered, tried console.log to see if my layout was obstructing that, but no use. Please help me
It should be inside the Switch component but you can wrap it with a Layout component like that.
const Headers = () => (
<Layout>
<ul>
<li>
<Link to="/admin">Admin</Link>
</li>
<li>
<Link to="/profile">Profile</Link>
</li>
<li>
<Link to="/employees">Employees</Link>
</li>
</ul>
</Layout>
);
function App() {
return (
<Router>
<Layout>
<Header></Header>
<Switch>
<Route exact path="/admin" render={() => <Admin />} />
<Route exact path="/employees" render={() => <Employees/>}/>
<Route exact path="/profile" component={Profile} />
</Switch>
</Layout>
</Router>
);
}
If your URL is changing but the content is not being rendered, the problem is this, apart from wrapping the Routes as mentioned in #G.aziz 's answer since the routes are children WRT layout components we have to use {props.children} inside the layout component to render the content like so...
Layout.jsx
<div>
<Sidebar />
<Navbar />
{props.children} // here we are rendering the routes which we mentioned in the switch component in App.js
</div>
For me this solution fixed. Also please refer this question for further information. React-router v4, URL changing but component doesn't render

Using Header globally in react using react-router-dom

I am currently using react-router-dom to create navigation within my web app.
My index.js and App.js look like:
Index.js
ReactDOM.render(
<BrowserRouter>
<Provider store={store}>
<App />
</Provider>
</BrowserRouter>,
document.getElementById('root')
);
App.js
class App extends React.Component {
render() {
return (
<BrowserRouter>
<div>
<Route exact path ='/' component={Home} />
<Route path ='/container' component={Container} />
<Route path ='/profile' component={ProfilePage} />
</div>
</BrowserRouter>
);
}
}
I idea was that if Home contains the header and the sidebar, it would also keep it for other components like Container and ProfilePage.
My Home's render looks like:
render() {
return (
<div>
<Header />
<div className="App">
<Sidebar />
<Container className="container-comp" />
{this.renderLoggingOutput()}
</div>
</div>
);
}
But when I Link to /profile, it just shows me the ProfilePage component without the header and the sidebar.
Any help?
Put your header outside the routes:
class App extends React.Component {
render() {
return (
<BrowserRouter>
<Header /> <-------- place here or outside the routes at a minimum
<div>
<Route exact path ='/' component={Home} />
<Route path ='/container' component={Container} />
<Route path ='/profile' component={ProfilePage} />
</div>
</BrowserRouter>
);
}
}
I have a similar structure in one of my apps.
the routes look like this:
class App extends Component {
render() {
return (
<BrowserRouter>
<div className="App">
<Navbar />
<Switch>
<Route exact path='/' component={Dashboard}/>
<Route path='/character/:id' component={CharacterDetails}/>
<Route path='/encounter/:id' component={Encounter}/>
.........
</Switch>
</div>
</BrowserRouter>
);
}
}
export default App;
The only job of a route is to mount a component. If you want omnipresent components across all routes, treat the routes as children to a base component.
class App extends React.Component {
render() {
<div>
<Header />
<Sidebar />
{this.props.children}
</div>
}
}
const Routes = () => (
<App>
{/* your routes here */}
</App>
)

React Router doesn't change the component

I setup React Router but it doesn't work.
I see that URL has changed, I see it in the history of browser. But the page doesn't change.
I want to go to other component which should look like a separate page (not related to the old page, from where I go).
How can I do that?
render() {
return (
<Link to={`/details/${this.props.movie.id}`}>
<div>
<p>{this.props.movie.title}</p>
<div>
<img
src={IMG_URL + this.props.movie.poster_path}
className='preview'
alt={this.props.movie.overview}/>
</div>
<Route path='/details/:number' component={MovieDetails}/>
</div>
</Link>
);
}
index.js:
ReactDOM.render(
<Provider store={store}>
<BrowserRouter>
<Main />
</BrowserRouter>
</Provider>,
document.getElementById('root'));
Your routes should be declared at a higher level, not as a child of a Link
For example in index.js
<Router>
<div>
<Route exact path="/" component={Main} />
<Route path="/details/:number" component={MovieDetails} />
</div>
</Router>

Categories

Resources