Nesting Routes in React Router 4 (Tried wrapping routes in component) - reactjs

I am trying to wrap my routes so I can render something on every route, such as a header or any static content. I have looked at this post here:
Nested Routes in React Router v4
I tried wrapping my routes like they have there, but now the only thing that shows is the wrapping component, none of the children show.
So the only thing that shows is on the / and /dashboard routes:
Home Component
Dashboard
Here is the code:
Wrapping routes:
<Home>
<Switch>
<Route path="/dashboard" component={Layout} />
<Route component={NotFound} />
</Switch>
</Home>
Home component:
import React, { Component } from 'react';
import { Link } from 'react-router-dom';
class Home extends Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<h2>Home component</h2>
<Link to="/dashboard">Dashboard</Link>
</div>
);
}
}
export default Home;
Layout component:
import React, { Component } from 'react';
class Layout extends Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<h2>Layout Component</h2>
<h2>Layout Component</h2>
</div>
);
}
}
export default Layout;

Have you tried putting {this.props.children} in your Home component?
import React, { Component } from 'react';
import { Link } from 'react-router-dom';
class Home extends Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<h2>Home component</h2>
<Link to="/dashboard">Dashboard</Link>
{this.props.children}
</div>
);
}
}
export default Home;

Your layout needs a component, or instruction to know where to render the children.
Otherwise the router won't know where the children routes need to appear. The child component is passed to the layout as a property called children. You need to add this where you want it to appear:
{props.children}
Like:
import React, { Component } from 'react';
class Layout extends Component {
constructor(props) {
super(props);
}
static propTypes = {
children: PropTypes.node.isRequired,
}
render() {
return (
<div>
<h2>Layout Component</h2>
{props.children}
</div>
);
}
}
export default Layout;
I personally prefer using . react router config But if you use the bare router that should do it.

Related

ReUse of class component in react

Im new to react and in the application im working im using a class component Summary
class SummaryList extends React.Component {
//code for the summarylist component here
}
class Summary extends React.Component {
render() {
return (
<Switch>
<Route path="/apply" component={Advance} />
<Route path="/summary/edit/:id" component={EAdvance} />
<Route path="/summary" component={SummaryList} />
</Switch>
);
}
}
export default Summary;
Im using this Summary in other page by importing it and using the component as Summary...
Now the isssue here is i need to use the SummaryList present in Summary in other place....when im trying to import Summay again....its stopped displaying the first place tried with exporting SummaryList seperately below export default Summary...by putting as export {SummaryList} and tried importing it in the second place and in the first place used Summary only....but its not working
If i need to reuse the component what shoud i do...cant i import the same component two times in my application
Yes you can export and import different components and render it multiple times.
Eg:-
App.js
import React, { Component } from 'react';
import Header from './Header';
import Main from './Main';
class App extends Component {
render() {
return (
<div>
<Header />
<Main />
</div>
);
}
}
export default App;
Header.js
import React, { Component } from 'react';
import Main from './Main';
class Header extends Component {
render() {
return (
<header>
<h1>Header Component</h1>
<Main/>
</header>
);
}
}
export default Header;
Main.js
import React, { Component } from 'react';
class Main extends Component {
render() {
return (
<main>
<p>Main Component</p>
</main>
);
}
}
export default Main;
Here Main in rendered in App.js and Header.js

Issues passing props via react-router-dom

I am attempting to pass data via react-router-dom, specifically I wanted to hold state data in the App.js file which I am using to route to different pages. I can't get the props to pass. What am I doing off here? Below is an example of what I am trying to do:
App.js
import React, { Component } from 'react';
import Home from './Home';
import {BrowserRouter as Router, Route,Switch, withRouter } from 'react-router-dom';
class App extends Component {
constructor(props) {
super(props);
this.state = {
testProps:7
}
}
render() {
return (
<Router>
<div>
<Route
exact path="/"
component = {Home}
render={(props) => <Home testProps={this.state.testProps} {...props} />}/>
</div>
</Router>
);
}
}
export default App;
Home.js
import React, { Component } from 'react';
class Home extends Component {
render() {
return (
<div>
{`passing props from state: ${this.props.testProps}`}
</div>
);
}
}
export default Home;
In my home page I see: passing props from state: undefined. Am I approaching this incorrectly?

How to pass props in react router

I have an App, a Navbar and a Content class, I am trying to pass a prop from navbar to content that will be rendered when I redirect to the content page.
App.js
import React, { Component } from 'react';
import { BrowserRouter as Router, Route } from 'react-router-dom';
import Navbar from './components/Home/Navbar';
import Content from './components/Home/Content';
export default class App extends Component {
render() {
return (
<Router>
<div>
<Navbar />
<Route path="/content" component={Content} render={(props) => <Navbar {...props} test={this.state.test} />} />
</div>
</Router>
);
}
}
Navbar.js
import React from 'react';
class Navbar extends React.Component {
constructor(props) {
super(props);
this.state = {
test: 'test',
}
}
render() {
return (
<div>
This is my navbar
</div>
);
}
}
export default Navbar;
Content.js
import React from 'react';
class Content extends React.Component {
constructor(props) {
super(props);
this.state = {
x: 'x',
test: this.props.test
}
}
render() {
return (
<div>
<p>{this.state.x}</p>
<p>{this.state.test}</p>
</div>
);
}
}
export default Content;
The problem that I am having is that is when I redirect to the content page, the state from the navbar class is not being passed through to it. How do I fix this?
The problem mostly lays in the fact that you are using both component and render props in your Route, you should use only one. If you do not want to change or pass along anything from where your Route is defined, you should use component property.
If you do wish to pass along some information at that point, use the render prop as you have done (however, I believe you really wanted to render the Content component and not the NavBar as in your OP)
<Route path="/content" render={(props) => <Content {...props} test={this.state.test} />} />
Then you really don't need any of your local state you were displaying, and content could be a functional component instead, like
const Content = ({ x, test }) => (
<>
<p>{ x }</p>
<p>{ test }</p>
</>);
where x and test would be destructured from your props, giving you easy access to it (you could also use (props) and then props.test and props.x depending on how you like to write it)
u can pass state like this with redirect :
<Redirect to={{
pathname: '/content',
state: { test: '123' }
}}
/>
and for accessing it :
this.props.location.state.test

How to change page title on separate header component depending on route with React?

I am using React and have my project structured in a way that I have layout components and then the main page components. I want to change the title of the page in the header component depending on which route the user came to.
Here is my App.jsx:
import React, { Suspense, lazy, Component } from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import Header from './layout/Header.jsx';
import Footer from './layout/Footer.jsx';
const Home = lazy(() => import('./pages/Home.jsx'));
const Weather = lazy(() => import('.pages/Weather.jsx'));
const Encryption = lazy(() => import('./pages/Encryption.jsx'));
const Video = lazy(() => import('./pages/Video.jsx'));
class App extends Component {
render() {
return (
<Router>
<>
<Header/>
<Suspense fallback={<div>Loading...</div>}>
<Switch>
<Route exact path="/" component={Home}/>
<Route path="/weather" component={Weather}/>
<Route path="/encryption" component={Encryption}/>
<Route path="/video" component={Video}/>
</Switch>
</Suspense>
<Footer/>
</>
</Router>
);
}
}
export default App;
My Header.jsx component is like so:
import React, { Component } from 'react';
class Header extends Component {
constructor(props) {
super(props);
}
render() {
return (
<h1>Page Title</h1>
);
}
}
export default Header;
import React, { Component } from "react";
import { withRouter } from "react-router-dom";
class Header extends Component {
constructor(props) {
super(props);
}
render() {
const path = this.props.location.pathname.slice(1);
return (
<div>
<h1>{path}</h1>
</div>
);
}
}
export default withRouter(Header);
Working example here: https://codesandbox.io/s/zl3y72k0pp
thre HOC withRouter will provide the props match, location and history to your component.
then your can use location.pathname to manage the rendering of your component

How to access url parameter in a react component

I have a react component which is loaded on routing
I need to access a parameter from the url inside the components constructor
How do I do it?
can I access it like this:
class CustomCoponent extends React.Component {
constructor(props,{match}) {
}
}
You can access route parameter in react-router-dom v4.x, by getting params from the match props.
Where you define your routes,
import { BrowserRouter as Router, Switch, Route, Link } from 'react-router-dom';
...
<Router>
<App>
<Switch>
<Route exact path="/" component={List} />
<Route path="/:parameterToAccess" component={CustomComponent} />
</Switch>
</App>
</Router>
...
In your component,
class CustomComponent extends React.Component {
constructor(props) {
super(props);
this.routeParam = props.match.params.parameterToAccess;
}
}
if you use routing then you can specify your route to expect the parameter.
<Route path='/yourpath/:ParamName' component={CustomComponent}/>
your component needs to be wrapped in the withRouter HOC for you to access this.
import {withRouter} from 'react-router-dom';
class CustomComponent extends React.Component{
constructor(props){
}
//**ACCESS PARAMETER VALUE LIKE THIS**
sample(){
let Paramvalue=this.props.match.params.ParamName;
}
}
export default withRouter(CustomComponent);
You can do it like this:
class CustomComponent extends React.Component {
constructor({ match, ...props }) {
console.log(match.params)
}
}
As {match} is passed to the component as a prop(property) so we can access this prop as a normal prop way.
class CustomComponent extends React.Component {
console.log(this.props.match.url)
}
Routes
import logo from './logo.svg';
import './App.css';
import {BrowserRouter as Router,Route,Switch} from 'react-router-dom';
import UpdateEmployeeComponent from './components/UpdateEmployeeComponent';
function App() {
return (
<div>
<Router>
<div className="container">
<Switch>
<Route path="/update-employee/:id" component={UpdateEmployeeComponent}></Route>
</Switch>
</div>
</Router>
</div>
);
}
export default App;
Component
import React, { Component } from 'react';
class UpdateEmployeeComponent extends Component {
constructor(props){
super(props);
this.state ={
id : this.props.match.params.id
}
console.log('Employee Id ::: '+this.id);
}
render() {
return (
<div>
</div>
);
}
}
export default UpdateEmployeeComponent;

Resources