React Router render component on a separate page - javascript

I started my first React Project and want to build my Design Portfolio by myself. So it's also my first time working with React Router or try to combine Components with each other by clicking a button.
I want to render all standard components in App.js and want to link only my project with the description project pages with a button. So if the user clicked on the button they will linked to the description of this project.
But surprise it doesn't work. My problem now is that the description page rendered in the same page as the standard component like "About, Navbar, Contact" rendered. But i want that the description page from the projects rendered in a seperate page. What can i do that this work?
I guess this is my relevant code to understand what i've made so far. But if you need more snippets please say it. :)
App.js
import React, { useState, useRef } from 'react';
import Navbar from './components/Navbar';
import Footer from './components/Footer';
import Contact from './components/Contact';
import Hero from './components/Hero';
import About from './components/About';
import Cards from './components/Cards';
import Sidebar from './components/Sidebar';
import Projects from './components/Projects';
import ProjectPath from './components/ProjectPath';
import Smartdress from './pages/Smartdress';
import Nazzle from './pages/Nazzle';
import Storyline from './pages/Storyline';
import Hel from './pages/Hel';
import Songstories from './pages/Songstories';
import { BrowserRouter as Router, Switch, Route } from 'react-router-dom';
function App() {
return (
<>
<Router>
<Navbar />
<Hero />
<Projects />
<Switch>
<Route exact path='/project/smartdress' component={Smartdress} />
<Route exact path='/project/nazzle' component={Nazzle} />
<Route exact path='/project/storyline' component={Storyline} />
<Route exact path='/project/hygienelab' component={Hel} />
<Route exact path='/project/songstories' component={Songstories} />
</Switch>
<About />
<Contact />
<Sidebar />
<Footer />
</Router>
</>
);
}
export default App;
Note: /pages/Smartdress -> are the description to the projects
Projects.js
import React, { useState } from 'react';
import CardItems from './CardItems';
import nazzle from '../assets/nazzle.png';
import smartdress from '../assets/smartdress.png';
import storyline from '../assets/2.png';
import hel from '../assets/hel.png';
import Nazzle from '../pages/Nazzle';
import Smartdress from '../pages/Smartdress';
import Hel from '../pages/Hel';
import Storyline from '../pages/Storyline';
import Songstories from '../pages/Songstories';
import {
BrowserRouter as Router,
Switch,
Route,
Link,
useRouteMatch,
useParams,
} from 'react-router-dom';
function Projects() {
return (
<div id='projects' className='container mx-auto'>
<h1 className='line absolute ml-8 -mt-2 z-0 text-xl'>Projects</h1>
<CardItems
bg='bg-smartdress'
text='Smartdress'
subtitle='Project (Studium)'
description='Spielerisch die Natur erkunden und
spannende Rätsel mit Augmented
Reality lösen'
src={smartdress}
link='/project/smartdress'
/>
<CardItems
bg='bg-nazzle'
text='Nazzle'
subtitle='Project (Studium)'
description='Spielerisch die Natur erkunden und
spannende Rätsel mit Augmented
Reality lösen'
src={nazzle}
link='/project/nazzle'
/>
<CardItems
bg='bg-storyline'
text='Storyline'
subtitle='Forschungsprojekt (Studium)'
description='Companion für Schüler zur
spielerischen Prävention von
Fake News und Cyber Mobbing
in sozialen Netzwerken'
src={storyline}
link='/project/storyline'
/>
<CardItems
bg='bg-hel'
text='Hygiene Lab'
subtitle='Client work'
description='Schaffen eines erzählenswertens
Erlebnis vom Besuch öffentlicher
Toiletten mit kontaktlosen Produkten'
src={hel}
link='/project/hygienelab'
/>
<CardItems
bg='bg-nazzle'
text='Nazzle'
subtitle='Project (Studium)'
description='Spielerisch die Natur erkunden und
spannende Rätsel mit Augmented
Reality lösen'
src={nazzle}
link='/project/songstories'
/>
</div>
);
}
export default Projects;
Note: Projects render all cards of the single projects
CardItem.js
import React from 'react';
import Projects from '../components/Projects';
import Nazzle from '../pages/Nazzle';
import Smartdress from '../pages/Smartdress';
import Hel from '../pages/Hel';
import Storyline from '../pages/Storyline';
import Songstories from '../pages/Songstories';
import { BrowserRouter as Router, Switch, Route, Link } from 'react-router-dom';
function CardItems(props) {
return (
<div className='container'>
<div className='my-12 mx-8 sm:mx-16 lg:mx-32 xl:mx-48 2xl:mx-80'>
<div
className={`shadow-md rounded overflow-hidden flex flex-col lg:flex-row ${props.bg}`}
>
<img
className='z-0 max-h-64 px-4 sm:max-h-80 order-1 lg:order-2 mx-auto my-12 sm:my-16 lg:mr-8 lg:max-h-96 xl:mr-16'
src={props.src}
></img>
<div className='flex flex-col justify-around order-2 lg:order-1 mb-12 sm:mb-12 mx-8 sm:mx-16'>
<div className=''>
<h1 className='font-bold'>{props.text}</h1>
<h3>{props.subtitle}</h3>
<p className='text-gray-700'>{props.description}</p>
</div>
<div className='mt-4'>
<div className='justify-center flex mt-2 lg:justify-start'>
<Link
to={props.link}
className='btn bg-indigo-700 hover:bg-indigo-300 font-bold text-white rounded shadow-md'
>
Read more
</Link>
</div>
</div>
</div>
</div>
</div>
<Router></Router>
</div>
);
}
export default CardItems;
Note: for better understanding how the cards look likes

Any component not inside a specific route will be shown on all routes.
In your case, since the About, Contact, and Sidebar components are outside the specific routes, they will be rendered for all routes - including the description page.
Try putting the components that you don't want rendered on the description page inside their own route. For example, the following should avoid rendering the About, Contact, and Sidebar components on the description page (note the comments in the code).
function App() {
return (
<>
<Router>
<Navbar />
<Hero />
<Projects />
<Switch>
<Route exact path='/project/smartdress' component={Smartdress} />
<Route exact path='/project/nazzle' component={Nazzle} />
<Route exact path='/project/storyline' component={Storyline} />
<Route exact path='/project/hygienelab' component={Hel} />
<Route exact path='/project/songstories' component={Songstories} />
</Switch>
<Switch>
<Route exact path='/project/smartdress' /> {/* render no components on the description page */}
<Route path='/project'> {/* render these components on any page starting with project ONLY IF it has not been matched by an earlier `Route` in this `Switch` */}
<About />
<Contact />
<Sidebar />
</Route>
</Switch>
<Footer />
</Router>
</>
);
}

Related

You should never have more than one router in your app

You cannot render a inside another . You should never have more than one in your app.
Why am I having this issue? I have checked my code and I dont have a Router inside another Router. In fact, i only have one router on my app.
This is the component:
import React from 'react';
import { BrowserRouter, Route, Routes } from "react-router-dom";
import Portfolio from '../pages/Portfolio';
function Menu()
{
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<Portfolio />} />
</Routes>
</BrowserRouter>
);
};
export default Menu;
And I call it from this component:
import React from 'react';
import AboutMe from '../components/AboutMe';
import Header from '../components/Header';
import Menu from '../components/Menu';
import Particle from '../components/Particle';
import Services from '../components/Services';
import Skills from '../components/Skills';
function Portfolio()
{
return (
<React.StrictMode>
<Particle />
<Menu />
<Header />
<div className='d-flex flex-column mt-5' id='about-me-services'>
<div><AboutMe /> </div>
<div><Services /> </div>
</div>
<Skills />
</React.StrictMode>
);
}
export default Portfolio;
Thanks for your help :)
Finally, Menu contains a Portfolio, which contains a Menu, which contains a Portfolio, which contains... etc. as super said. Thanks for your help

Routing not working with react-router-dom

I'm working on one of my friend's half-built React Project. I'm trying to route my react-app with react-router-dom. The components inside the <switch> are not working. Here's my
App.js
import React from 'react';
import Header from './components/Header';
import Main from './components/Main';
import Footer from './components/Footer';
import ProcessInput from './components/ProcessInput';
// Import react-router-dom
import { BrowserRouter as Router, Switch, Route} from 'react-router-dom';
function App() {
return(
<Router>
<div className="App">
<Header />
<Switch>
<Route path="/" exact component={Main} />
<Route path="/process" component={ProcessInput} />
</Switch>
<Footer />
</div>
</Router>
);
}
export default App;
Main.js
import React from 'react';
import Slider from './Slider';
import Card1 from './Card1';
import Card2 from './Card2';
import Prompt from './Prompt';
class Main extends React.Component {
render() {
return (
<div>
<main>
<Slider />
<Card1 />
<Card2 />
<Prompt />
</main>
</div>
)
}
}
export default Main;
The <Header /> and <Footer /> which are outside the <Switch> are showing anyways as intended. But, I want the Main component to be loaded as a root component (Launcher).
There are no errors on the console.
Please help me get to know what am I doing wrong. Thanks in advance :)
<Route path="/" exact>
<Main/>
</Route>
<Route path="/process"><ProcessInput/>
</Route>
This is the old way to do it. You can try this

Issue with React Router

I'm using react-router-dom but my routes are somehow not working. the routes are not redirected to the component. I don't have any error in the console, and I did npm install react-router-dom. I can't see what I've done wrong. You can find my code below. Any help will be welcome.
This is my App.js page
import React from 'react';
import './App.css';
import {
BrowserRouter as Router,
Switch,
Route
} from "react-router-dom";
import LoginButton from './components/LoginButton';
import Register from './components/Register';
import Login from './components/Login';
function App() {
return (
<Router>
<div>
<div className="cover d-flex justify-content-center align-items-center">
<div className="text-white">
<h1 className="text-center fw-bold">GREEN</h1>
<p className="lead fw-bold">CARBON FOOTPRINT CALCULATOR</p>
<LoginButton />
</div>
</div>
<Switch>
<Route path="/register">
<Register />
</Route>
<Route path="/login">
<Login />
</Route>
<Route path="/">
<App />
</Route>
</Switch>
</div>
</Router>
);
}
export default App;
This is the component page
import React, { Component } from 'react';
import './LoginButton.css'
import { Link } from "react-router-dom";
export default class LoginButton extends Component {
render() {
return (
<div>
<div className="login-container">
<Link to="/register"><button className="signup-button">SIGN UP</button></Link>
<Link to='/login'><button className="login-button">LOG IN</button></Link>
</div>
</div>
)
}
}
assuming you know the difference between import {component} from component and import component from component. In my example below I'm using the import {component} from component;.
The React Router works something like this:
<Router>
<div>
<div className="cover d-flex justify-content-center align-items-center">
<div className="text-white">
<h1 className="text-center fw-bold">GREEN</h1>
<p className="lead fw-bold">CARBON FOOTPRINT CALCULATOR</p>
<LoginButton />
</div>
<Switch>
<Route path='/' component={Home} exact />
<Route path='/register' component={Register} exact />
<Route path='/login' component={Login} exact />
</Switch>
Edit:
You're using <Route path="/"> <App /> </Route> which is the entry point itself in App.js. You've a syntax error in your App.js file.
Not sure but I guess that putting <Link>, <button> together can make "event bubbling" problem.
To make sure this problem, How about to change <button> to just plain dom like <div>

Why wont my create-react-app content center?

I used create-react-app and have been playing around with it. I understand the "app" class is supposed to center the content, and it did when I barely anything. But now it isn't doing that. Can someone tell me where I'm going wrong?
App.js
import React from "react";
import './App.css';
import { Route, BrowserRouter as Router } from "react-router-dom";
import Home from "./pages/home";
import About from "./pages/about";
function App() {
return (
<div className="app">
<Router>
<Route path="/" exact component={Home} />
<Route path="/about" exact component={About} />
</Router>
</div>
);
}
export default App;
about.js
import React from "react";
import { Button, Breadcrumb, Card } from "react-bootstrap"
import 'bootstrap/dist/css/bootstrap.min.css'
function About() {
return (
<div className="app">
<h1>ABOUT PAGE</h1>
<a href="/">
<img src="https://www.searchpng.com/wp-content/uploads/2019/02/Back-Arrow-Icon-PNG-715x715.png" height="50px" />
</a>
<Card className="mb-3" style={{ color: "#000"}}>
<Card.Img/>
<Card.Body>
<Card.Title>
Card Example
</Card.Title>
<Card.Text>
This is an example of react bootstrap cards
</Card.Text>
</Card.Body>
</Card>
<Breadcrumb>
<Breadcrumb.Item>Test</Breadcrumb.Item>
<Breadcrumb.Item>Test 2</Breadcrumb.Item>
<Breadcrumb.Item>Test 3</Breadcrumb.Item>
</Breadcrumb>
<Button variant="success">Test Button</Button>
</div>
)
}
export default About;
In create-react-app, there is a file App.css with class .App:
.App {
text-align: center;
}
If you'd like to use it, you will have to use capitalized name of the class, since that's how it is defined in css file.

ReactJS Header and Footer

I am trying to create a Layout component which would render the Header and Footer. So that I can later on use the Layout like
<Layout> ... </Layout>
I have used Routing in the Header and Footer, obviously. To do this, I need to use
<Router history...
<Route path...
When I do this one after the other(for header and footer: though I feel that this is wrong) in my layout.js. It works. The header and footer are shown in the browser. However, they don't work properly. On refresh the footer vanishes and sometimes both, the header and the footer. I strongly believe that rendering Router one after the other is the reason for this malfunctioning, but I can't figure out the correct approach. Moreover, I don't want to use the following snippets
header.js
import React from 'react';
import {Link} from 'react-router'
import {Navbar, NavItem} from 'react-materialize';
export default React.createClass({
render(){
return (
<div>
<Navbar brand='logo' right>
<NavItem><Link to="/Home" activeClassName="active">Home</Link></NavItem>
<NavItem><Link to="/Sign-In" activeClassName="active">Sign In</Link></NavItem>
<NavItem><Link to="/Register" activeClassName="active">Register</Link></NavItem>
</Navbar>
{this.props.children}
</div>
)
}
})
footer.js
import React, {Component} from 'react';
import {Link} from 'react-router'
import {Footer} from 'react-materialize';
import '../../resource/template.css'
class RT_Footer extends Component{
render(){
return (
<div>
{this.props.children}
<Footer copyrights="© 2015 Copyright Text"
moreLinks={
<Link className="grey-text text-lighten-4 right" href="#!">More Links</Link>
}
links={
<ul>
<li><Link to="/About Us" className="grey-text text-lighten-3">About Us</Link></li>
<li><Link to="/Terms & Conditions" className="grey-text text-lighten-3">Terms & Conditions</Link></li>
<li><Link to="/Help" className="grey-text text-lighten-3">Help</Link></li>
<li><Link to="/Contact Us" className="grey-text text-lighten-3">Contact Us</Link></li>
</ul>
}
className='example'
>
<h5 className="white-text">Footer Content</h5>
<p className="grey-text text-lighten-4">You can use rows and columns here to organize your footer content.</p>
</Footer>
</div>
);
}
}
export default RT_Footer;
layout.js
import {Router, Route, browserHistory} from 'react-router'
class Layout extends Component {
render(){
return (
<div>
<span>
<Router history={browserHistory}>
<Route path="/" component={Header}>
<Route path="/Home" component={Home}/>
<Route path="/Sign-In" component={SignIn}/>
<Route path="/Register" component={Register}/>
</Route>
</Router>
</span>
<span>
<Router history={browserHistory}>
<Route path="/" component={RT_Footer}>
<Route path="/About Us" component={About}/>
<Route path="/Terms & Conditions" component={TC}/>
<Route path="/Register" component={Register}/>
</Route>
</Router>
</span>
</div>
);
}
}
export default Layout;
Then I simply rendered Layout in index.js
I suggest that you don't render the Router component twice (I haven't checked but you probably can't).
So, how the Router component works :
You give the router an history (via the history props), here you use the browserHistory from the same library wich is fine.
Then you define all the existing routes for your application using the Route component with a path, and the component to load if the browser url match this path property.
Now, in your case I suggest you to do something like that :
app.js
import {Router, Route, browserHistory} from 'react-router'
import Layout from './components/Layout'
// Import here all the required components used by the router such as SignIn, Register, ...
render(
<Layout>
<Router history={browserHistory}>
<Route path="/" component={RT_Footer}>
<Route path="/About Us" component={About}/>
<Route path="/Terms & Conditions" component={TC}/>
<Route path="/Register" component={Register}/>
// Add as many Route components as needed
</Router>
</Layout>,
document.getElementById('react-anchor')
Then your layout file should look like this :
layout.js
import Header from './Header'
import Footer from './Footer'
import React, {Component} from 'react'
class Layout extends Component {
render() {
return (
<div>
<Header />
{this.props.children}
<Footer />
</div>
)
}
}
And in your Header and Footer component, render whatever you want, to provide link to load the requested component you can use from react-router or some other way the library offer (see their documentation)
Edit :
Careful about route Path, like "Terms & Conditions" is probably not a valid path

Categories