how to use router inside a routed component - reactjs

My App.js:
<Router>
<Header/>
<Switch>
<Route exact path="/" component={HomeScreen} />
<Route exact path="/screenOne" component={OneScreen} />
<Route exact path="/screenTwo" component={TwoScreen} />
</Switch>
</Router>
The <Header /> has three links to the respective components viz. HomeScreen, OneScreen, TwoScreen.
I want my <TwoScreen /> to be exactly like this baseComponent(i.e App.js) where I have some links and when I click those links, the components corresponding to the link/path gets rendered.
What is the best way to approach this?

there is an example on the react-router site that meets your need, under nesting, you can check it out https://reactrouter.com/web/example/nesting (for just web)
But for me, I simply declare them all in one place/component, especially on react-router-native, if you're doing react-native.
below is the example from their website for web
import React from "react";
import {
BrowserRouter as Router,
Switch,
Route,
Link,
useParams,
useRouteMatch
} from "react-router-dom";
// Since routes are regular React components, they
// may be rendered anywhere in the app, including in
// child elements.
//
// This helps when it's time to code-split your app
// into multiple bundles because code-splitting a
// React Router app is the same as code-splitting
// any other React app.
export default function NestingExample() {
return (
<Router>
<div>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/topics">Topics</Link>
</li>
</ul>
<hr />
<Switch>
<Route exact path="/">
<Home />
</Route>
<Route path="/topics">
<Topics />
</Route>
</Switch>
</div>
</Router>
);
}
function Home() {
return (
<div>
<h2>Home</h2>
</div>
);
}
function Topics() {
// The `path` lets us build <Route> paths that are
// relative to the parent route, while the `url` lets
// us build relative links.
let { path, url } = useRouteMatch();
return (
<div>
<h2>Topics</h2>
<ul>
<li>
<Link to={`${url}/rendering`}>Rendering with React</Link>
</li>
<li>
<Link to={`${url}/components`}>Components</Link>
</li>
<li>
<Link to={`${url}/props-v-state`}>Props v. State</Link>
</li>
</ul>
<Switch>
<Route exact path={path}>
<h3>Please select a topic.</h3>
</Route>
<Route path={`${path}/:topicId`}>
<Topic />
</Route>
</Switch>
</div>
);
}
function Topic() {
// The <Route> that rendered this component has a
// path of `/topics/:topicId`. The `:topicId` portion
// of the URL indicates a placeholder that we can
// get from `useParams()`.
let { topicId } = useParams();
return (
<div>
<h3>{topicId}</h3>
</div>
);
}

Related

implement nested routing in React js react-router-dom V6 [duplicate]

This question already has an answer here:
Nested routing in react-router-dom V6
(1 answer)
Closed 1 year ago.
I have a folder structure in my project like this :
---login
---main
in the App I implement routing like this that works fine for me :
import { BrowserRouter as Router, Routes, Route} from 'react-router-dom';
<div className="App">
<Router>
<Routes>
<Route path="/" element={<Login />} />
<Route path="/main" element={<Main />} />
</Routes>
</Router>
</div>
but my problem starts here . When I go to the main page, I want to render the nested routing inside of the main page . I code like that but unfortunately nothing work for me fine.
here is the code in my main component .
import {
BrowserRouter as Router,
Routes,
Route,
Outlet,
Link
} from 'react-router-dom';
<
<h1>
hello Home
</h1>
<Link to="/main/child1">
child 1
</Link>||||
<Link to="/main/child2">
child 2
</Link>
<Link to="/">
log out
</Link>
<Outlet />
<Routes>
<Route path="/main/child1" element={<Children1 />} />
<Route path="/main/child2" element={<Children2 />} />
</Routes>
I want to render the child at the under of my main component but nothing happen. and want to url change to "/main/child1" .
I would be really appreciate it if you can explain the detail .
Thanks.
here is the sample code sample is here
You can use the following code:
import React from "react";
import {
BrowserRouter as Router,
Switch,
Route,
Link,
useRouteMatch,
useParams
} from "react-router-dom";
export default function App() {
return (
<Router>
<div>
<ul>
<li>
<Link to="/">Login</Link>
</li>
<li>
<Link to="/main">Main</Link>
</li>
</ul>
<Switch>
<Route path="/">
<Login />
</Route>
<Route path="/main">
<Main />
</Route>
</Switch>
</div>
</Router>
);
}
function Login() {
return <h2>LoginPage</h2>;
}
function Main() {
let match = useRouteMatch();
return (
<div>
<h2>Main Page</h2>
<ul>
<li>
<Link to={`${match.url}/children`}>children</Link>
</li>
<li>
<Link to={`${match.url}/child1`}>
Child_One
</Link>
</li>
</ul>
<Switch>
<Route path={`${match.path}/:childId`}>
<Child />
</Route>
<Route path={match.path}>
<h3>Please select a child.</h3>
</Route>
</Switch>
</div>
);
}
function Child() {
let { childId } = useParams();
return <h3>Requested child ID: {childId}</h3>;
}
The Main page has its own with more routes that build on the /main URL path. You can think of the 2nd here as an "index" page for all children of the main page, or the page that is shown when no child is selected.
For more info, please refer: link

When matching url nested router not working

I have tried for several hours now but without success to identify the reason why this nested router does not work. In the following example in the main component a series of links are listed, among them /surveys that when matching will show the <Surveys /> component, within this component when the url matches /surveys/:id the <Answers /> component should be shown but it never shows. Could you help me identify the reason for this behavior
import ...
function App() {
// some logic
return (
<div>
<Router>
<div>
<nav>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/employees">Employees</Link>
</li>
<li>
<Link to="/surveys">Surveys</Link>
</li>
<li>
<Link to="/survey-creator">Survey creator</Link>
</li>
</ul>
</nav>
</div>
<Switch>
<Route path="/survey-creator">
<MySurveyCreator />
</Route>
<Route path="/employees">
<Employees employees={state.employees} />
</Route>
<Route path="/surveys" exact={true}>
<Surveys />
</Route>
<Route path="/" exact={true}>
<Home />
</Route>
</Switch>
</Router>
</div>
);
}
ReactDOM.render(<App />, document.getElementById("root"));
Surveys
import ...
function SingleSurvey({ id, name }) {
return (
<li>
<Link to={`/surveys/${id}`}>{name}</Link>
</li>
);
}
export default function Surveys() {
// some logic
return (
<div>
<h1>Survey</h1>
<Switch>
<ul>
{surveys.map(survey => (
<SingleSurvey key={survey.id} {...survey} />
))}
</ul>
<Route exact={true} path={`/${match.path}/:id`}>
<Answers />
</Route>
</Switch>
</div>
);
}
Answers
import React from "react";
import { useParams } from "react-router-dom";
export default function Answers() {
const { id } = useParams();
console.log(id);
return (
<div>
<h1>Answer</h1>
<h2>Current id is: {id}</h2>
</div>
);
}
Your nested route is in Serveys Component, So The Serveys Component has to match the url for the nested route but you put an exact keyword for it that won't match with the /surveys/:id
So in result you won't have a Serveys Component that renders <Answers /> Component.
No Servey No Answer :)
just change this:
<Route path="/surveys" exact={true}>
<Surveys />
</Route>
to this:
<Route path="/surveys">
<Surveys />
</Route>

React Nested Routing by `:id`

I am trying to create a blog style app with an "articles" page that has a list of posts which will render by postId. I have gotten the urls to generate and even my small <Post /> component to render, but when a post page renders the Articles content doesn't go away and the post content just renders below it. How do I fix this?
I have
App.js:
<Switch>
<Route exact path="/">
<Home />
</Route>
<Route exact path="/articles">
<Articles />
</Route>
</Switch>
Articles.js:
import React from 'react';
import {
Link,
useRouteMatch,
Switch,
Route,
} from 'react-router-dom';
import Post from '../Components/Post';
import Banner from './Banner';
const Articles = () => {
let match = useRouteMatch();
return (
<div className='Articles'>
<Banner title='Articles'/>
<h3>Please select a topic.</h3>
<ul>
<li>
<Link to={`${match.url}/geojsons`}>Geojsons</Link>
</li>
<li>
<Link to={`${match.url}/props-v-state`}>
Props v. State
</Link>
</li>
</ul>
<Switch>
<Route path={`${match.url}/:postId`}>
<Post />
</Route>
</Switch>
</div>
)
}
export default Articles;
Post.js:
function Post() {
let { postId } = useParams();
return <h3>POST - Requested topic ID: {postId}</h3>;
}
export default Post;
Screen shot of problem page:
This screenshot shows the page after you click on an article link. The Post content is what I have in the dashed red box and everything above it should only be a part of the Articles page.
I know it is only a couple files but to make it easier to mess with I put a simplified version of the repo on github. No styling or anything just an html version of the problem.
Since you want Article and Posts pages to be separate, you need to decouple your post route from Article route and render it in App.js instead of Articles.js
<Switch>
<Route exact path="/">
<Home />
</Route>
<Route path="/articles/:postId">
<Post />
</Route>
<Route exact path="/articles">
<Articles />
</Route>
</Switch>
and in Article.js
const Articles = () => {
let match = useRouteMatch();
return (
<div className='Articles'>
<Banner title='Articles'/>
<h3>Please select a topic.</h3>
<ul>
<li>
<Link to={`${match.url}/geojsons`}>Geojsons</Link>
</li>
<li>
<Link to={`${match.url}/props-v-state`}>
Props v. State
</Link>
</li>
</ul>
</div>
)
}

Routing pages into components: React

I have 3 components: Header.js, Main.js, and Footer.js, and App.js is like
const App = () => {
<Header/>
<Main/>
<Footer/>
}
In the Header.js I have links like About and Projects. I would like to be able when I click About in the header for example to display the page About.js in Main.js, and when I click Projects to display the page Projects.js in the Main.js component. I tried to use Routing in the Main.js component like
const Main = () => {
<Router>
<Switch>
<Route exact path='/' component={About.js} />
<Route exact path='/projects' component={Projects.js} />
</Switch>
</Router>
}
but it wouldn't allow me, saying that I cannot use Link outside a router, where I use Link in the Header.js. How can I achieve this?
The Header.js is the following
const Header = () => {
return (
<div>
<ul>
<li>
<Link to="/">
About
</Link>
</li>
<li>
<Link to="/projects">
Projects
</Link>
</li>
</ul>
</div>
)
}
You simply need to make sure your Router component surrounds any components doing routing. For simplicity, here’s the router surrounding your whole app at the App level.
const App = () => {
<Router>
<Header/>
<Main/>
<Footer/>
</Router>
}
Edit: make sure you’re passing your components correctly to the Routes:
const Main = () => {
<Switch>
<Route exact path='/' component={About} />
<Route exact path='/projects' component={Projects} />
</Switch>
}

Using React Router to control independent components

I am new to React/Redux and I'm struggling with controlling my app layout with React Router (What I am doing maybe beyond the realms of React Router). I have the following code setup:
INDEX.JS
ReactDOM.render(
<Provider store={createStoreWithMiddleware(reducers)}>
<Router history={ browserHistory } routes={ routes } />
</Provider>
, document.querySelector('#root'));
APP.JS
class App extends Component {
render() {
return (
<div>
<TopNavigation />
<SideNavigation />
<Stage />
</div>
);
}
}
SIDENAVIGATION.JS
render() {
const openSideNavDrawer = classNames({
'side-navigation-drawer': true,
'open': this.state.sideNavIsOpen
});
return (
<nav className="side-navigation">
<ul onMouseOver={ this.openSideNavDrawer.bind( this ) } >
<li>
<Link to="/project">1</Link>
</li>
<li>
<Link to="/pages">2</Link>
</li>
<li>
<Link to="/blocks">3</Link>
</li>
<li>
<Link to="/reorder">4</Link>
</li>
<li>
<Link to="/download">5</Link>
</li>
</ul>
<div className={ openSideNavDrawer } onMouseOut={ this.closeSideNavDrawer.bind( this ) } >
{ this.props.children }
</div>
</nav>
);
}
ROUTER.JS
import { Route, IndexRoute } from 'react-router';
export default (
<Route path="/" component={ App }>
<Route component={ SideNavigation }>
<Route path="/project" component={ Project } />
<Route path="/pages" component={ Pages } />
<Route path="/blocks" component={ Blocks } />
<Route path="/reorder" component={ Reorder } />
<Route path="/download" component={ Download } />
</Route>
</Route>
);
WIREFRAME WITH EXPLANATION
So far I have only attempted to wire the side navigation, I am receiving no errors but the routing is not working.
Please can anyone explain if:
a/ This is even possible with React Router?
b/ If it is possible what am I doing wrong?
Many thanks in advance.

Resources