conditional rendering react router dom - javascript

I am making an advertising website with reusable components that load with different graphics depending on what page it is. I am using react-router-dom Route exact path. I imagine i need to be able to read the state of that with my useEffect,[]. So how do i pass down the state so its able to be read by the component.
Please note that the component Hero appears in the functions for Home, Consultants and Solutions
const Hero = props => {
useEffect(() => {
console.log(props);
}, []);
return (
<Fragment>
<div className='grid-hero'>
<Fragment>
<div className='overlay'>
<div>
<p className='bg-dark'></p>
<img src={{ homeimg } || { consimg } || { solsimg }} alt='' />
</div>
</div>
</Fragment>
<Router>
<Fragment>
<Navbar />
<Switch>
<Route exact path='/' component={Home} />
<Route exact path='/consultants' component={Consultants} />
<Route exact path='/solutions' component={Solutions} />
<Route exact path='/contactus' component={ContactUs} />"
</Switch>
</Fragment>
</Router>
<div
className={
{pathname === "/" && ("grid-home")}
{pathname === "/consultants" && ("grid-consultants")}
{pathname === "/solutions" && ("grid-solutions")}
}>

maybe this is what you're looking for:
I've added Hero as top-level image component where your image would switch. I don't have the images, so I used strings, but if you import images like JSX, you'll be able to use this code by removing the img strings inside my Hero dummy component.
adding reference image import syntax for help:
import img from './img.png';
complete example:
import React, { Fragment } from "react";
import {
BrowserRouter as Router,
Route,
Link,
useLocation
} from "react-router-dom";
function BasicExample() {
return (
<Router>
<div>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/contactus">ContactUs</Link>
</li>
<li>
<Link to="/solutions">Solutions</Link>
</li>
</ul>
<hr />
<Hero />
<Route exact path="/" component={Home} />
<Route path="/contactus" component={ContactUs} />
<Route path="/solutions" component={Solutions} />
</div>
</Router>
);
}
const Hero = () => {
const homeimg = "HOME_IMAGE";
const consimg = "CONTACT_US_IMAGE";
const solsimg = "SOLUTIONS_IMAGE";
let img = null;
const location = useLocation();
if (location.pathname === "/") img = homeimg;
else if (location.pathname === "/contactus") img = consimg;
else if (location.pathname === "/solutions") img = solsimg;
return (
<Fragment>
<h3>{location.pathname}</h3>
<div className="grid-hero">
<Fragment>
<div className="overlay">
<div>
<p className="bg-dark" />
{img}
</div>
</div>
</Fragment>
</div>
</Fragment>
);
};
function Home() {
return (
<div>
<h2>Home</h2>
</div>
);
}
function ContactUs() {
return (
<div>
<h2>ContactUs</h2>
</div>
);
}
function Solutions() {
return (
<div>
<h2>Solutions</h2>
</div>
);
}
export default BasicExample;
codepen-link

Related

onclick of sidebar item issue in react

i am trying to create a simple react project. it has a navbar, sidebar and the main content area.
first a home component is displayed.
home.js
import { useState } from "react";
import Navbar from "../navbar/navbar";
import Sidebar from "../sidebar/sidebar";
import "./style.css";
import { useSelector, useDispatch } from 'react-redux'
function Home() {
const sidebarOpen = useSelector((state) => state.sidebarOpenState);
return (
<>
<Navbar />
<div className="home-box d-flex">
{sidebarOpen && <div className="p-2 flex-fill"><Sidebar /></div>}
</div>
</>
);
}
export default Home;
my navbar has a button which will change state sidebarOpen.
my sidebar looks like this->
sidebar.js
import "./style.css";
import { Link } from "react-router-dom";
function Sidebar() {
return (
<div className="divSidebar">
<ul>
<li>
<Link to="/chess">
<img className="sidebar-img" src="images/sidebar/chess.png"></img>
<span className="sidebar-text">Chess</span>
</Link>
</li>
<li>
<Link to="/volleyball">
<img
className="sidebar-img"
src="images/sidebar/volleyball.png"
></img>
<span className="sidebar-text">Volleyball</span>
</Link>
</li>
<li>
<Link to="/football">
<img
className="sidebar-img"
src="images/sidebar/football.png"
></img>
<span className="sidebar-text">Football</span>
</Link>
</li>
<li>
<Link to="/tabletennis">
<img
className="sidebar-img"
src="images/sidebar/table-tennis.png"
></img>
<span className="sidebar-text">TableTennis</span>
</Link>
</li>
<li>
<Link to="/rugby">
<img className="sidebar-img" src="images/sidebar/rugby.png"></img>
<span className="sidebar-text">Rugby</span>
</Link>
</li>
</ul>
</div>
);
}
export default Sidebar;
when i click on chess, the respective component should be loaded.
chess.js
function Chess() {
return (
<>
<h1>chess</h1>
</>
);
}
export default Chess;
but the problem is my sidebar disappears. i only want the main content area to be changed nothing else. can someone help? let me know if u want to some more code.
---------edit
i have added console.log in two places. one is in the navbar where the toggle method is defined and another is in redux store where toggle state is defined. both the places onclick is working. i am able to see message but the sidebar is not getting rendered.
---------edit 2
App.js
import "./App.css";
import Navbar from "./components/navbar/navbar";
import { Route, Routes } from "react-router-dom";
import Chess from "./components/chess/chess";
import Volleyball from "./components/volleyball/volleyball";
import Football from "./components/football/football";
import TableTennis from "./components/tabletennis/tabletennis";
import Rugby from "./components/rugby/rugby";
import Home from "./components/home/home";
function App() {
return (
<div className="App">
<Routes>
<Route exact path="/" element={<Home />} />
<Route
path="/chess"
element={
<>
<Navbar />
<Chess />
</>
}
/>
<Route
path="/volleyball"
element={
<>
<Navbar />
<Volleyball />
</>
}
/>
<Route
path="/tabletennis"
element={
<>
<Navbar />
<TableTennis />
</>
}
/>
<Route
path="/football"
element={
<>
<Navbar />
<Football />
</>
}
/>
<Route
path="/rugby"
element={
<>
<Navbar />
<Rugby />
</>
}
/>
</Routes>
</div>
);
}
export default App;
When you click on Chess you navigate to "/chess"
So if u can't see your Navbar there, is because you have to render it there too.
Or, render the Navbar outside de Routes from BrowsterRouter.
We need to see the components rendering on "/chess" and the react-router-dom config on app.js (or on the top lvl you declare it)
----- edit ------
Ok, look this:
function App() {
return (
<BrowserRouter>
<NavBar />
<Routes>
<Route path="/" element={<Home />} />
<Route path="/test" element={<Test />} />
</Routes>
</BrowserRouter>
);
}
If you refactor your brower like this is gona be more clean to understand the code and even easy to escale.
As u see, the navBar is outside the Routes, so its gona be visible in all routes.
then you can have this:
-> one path -> one element
your Links on navbar (or sidebar or whatelse) are gona work good.
i found a way. i rendered <Sidebar /> again in all my child components.
like this->
chess.js
function Chess() {
const sidebarOpen = useSelector((state) => state.sidebarOpenState);
return (
{sidebarOpen && (
<div className="p-2 flex-fill">
<Sidebar />
</div>
)}
)
}
this way when i click on button the state is updated and sidebar is rendered automatically.

React - Failed to execute 'removeChild' on 'Node'

When entering the website, you will be in Home component with path /
But if you switch page to About/Dashboard, below error occurs
Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node.
How to fix it?
example.js
import React, { useEffect } from "react";
import { BrowserRouter as Router, Switch, Route, Link } from "react-router-dom";
import ScrollMagic from "scrollmagic";
export default function BasicExample() {
return (
<Router>
<div>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/about">About</Link>
</li>
<li>
<Link to="/dashboard">Dashboard</Link>
</li>
</ul>
<hr />
<Switch>
<Route exact path="/">
<Home />
</Route>
<Route path="/about">
<About />
</Route>
<Route path="/dashboard">
<Dashboard />
</Route>
</Switch>
</div>
</Router>
);
}
function Home() {
useEffect(() => {
const scrollController = new ScrollMagic.Controller({
globalSceneOptions: { triggerHook: "onCenter" }
});
const scrollScene = new ScrollMagic.Scene({
triggerElement: "#pin",
duration: 2000,
offset: -50
})
.setPin("#pin")
.on("progress", function (e) {
console.log(e.progress);
});
scrollScene.addTo(scrollController);
}, []);
return (
<div id="pin">
<h2>Home</h2>
<div style={{ height: "1700px" }}>Another Stuff</div>
</div>
);
}
function About() {
return (
<div>
<h2>About</h2>
</div>
);
}
function Dashboard() {
return (
<div>
<h2>Dashboard</h2>
<div style={{ height: "1700px" }}>Another Stuff in Dashboard</div>
</div>
);
}
Codesandbox
https://codesandbox.io/s/react-router-basic-forked-q9iwm?file=/example.js
I dont know what you are trying to achieve with ScrollMagic, but the following block definitely works.
<React.Fragment id="pin">
<h2>Home</h2>
<div style={{ height: "1700px" }}>Another Stuff</div>
</React.Fragment>
Sandbox Link
Just to add, when I debugged, it looked like that when you are using setPin function, it is causing some issues.
The problem is in About/Dashboard function can you replace your div tag with <React.Fragment> and try. Fragments let you group a list of children without adding extra nodes to the DOM.
function About() {
return (
<React.Fragment>
<h2>About</h2>
</React.Fragment>
);
}
It seems the issue is with the useEffect code in your home component.
I commented that out and all seems well. See codesandbox https://codesandbox.io/s/react-router-basic-forked-7oysy?file=/example.js

React routing to endpoint but not rendering content

I can route to another endpoint, but the component content only appears on manual refresh.
I've seen this question asked here, here, and I've been checking out the reactrouter docs, amongst others. The solution always seems to be "add withRouter" or "make sure you're wrapping it in Router. I've done those things, but sadly got no where.
Here's the code:
App.js
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
function App() {
return (
<Router>
<Provider store={store}>
<div className="App">
<NavBar />
<Switch>
<Route exact path="/" component={Home} />
<Route path="/account" component={Account} />
</Switch>
</div>
</Provider>
</Router>
);
}
NavBar.js
import { BrowserRouter as Router, Link } from "react-router-dom";
import { withRouter } from "react-router";
function NavBar() {
return (
<Router>
<div className="navbar">
<h3>Connectory</h3>
<div className="buttons-container">
<Link>
<button>Settings</button>
</Link>
<Link to="/account"> // successfully redirects to /account, but doesn't render Account page content until refresh
<button>Account</button>
</Link>
</div>
</div>
</Router>
);
}
export default withRouter(NavBar);
EDIT: After comment suggestions, here's a code sandbox link and here;s the Account.js page:
import React from "react";
export default function Account() {
return (
<div>
<h3>This is the Account page</h3>
</div>
);
}
The Problem here is that, in your Navbar.js, you are re-setting your Routes again when they are already set in App.js.
<Switch>
<Route exact path="/" component={Home} />
<Route path="/account" component={Account} /> // Route for Applicatin set here
</Switch>
You do not need to do that again in. Check here.
https://codesandbox.io/s/gracious-germain-7fyry?file=/src/Navbar.js
Your Nabar should look like:
function NavBar() {
return (
<div className="navbar">
<h3>Connectory</h3>
<div className="buttons-container">
<Link to="/">
<button>Settings</button>
</Link>
<Link to="/account">
<button>Account</button>
</Link>
</div>
</div>
);
}
Hi i found a bug in your code and that's the reason because is not working.
in this component you are injecting the Router to the rest of the app.
function App() {
return (
<Router>
<div className="App">
<NavBar />
<Switch>
<Route exact path="/" component={Home} />
<Route path="/account" component={Account} />
</Switch>
</div>
</Router>
);
}
in this one you are injecting again the Router. That's why is not working you just have to remove the Router from de Navbar and it will work properly.
function NavBar() {
return (
<Router>
<div className="navbar">
<h3>Connectory</h3>
<div className="buttons-container">
<Link>
<button>Settings</button>
</Link>
<Link to="/account">
<button>Account</button>
</Link>
</div>
</div>
</Router>
);
}
like this
function NavBar() {
return (
<div className="navbar">
<h3>Connectory</h3>
<div className="buttons-container">
<Link>
<button>Settings</button>
</Link>
<Link to="/account">
<button>Account</button>
</Link>
</div>
</div>
);
}

Problem with correct routing in a React project

I have a trouble with correct routing in React project.
When I go into "Heroes" route, there is a list of "heroes" (this is a blog).
I can open a document by id-made link.
When I open the document, and then click on "Heroes", it is not rendered. It will render if I only the first open the main page or "about", and then open "Heroes".
Maybe someone can tell me, how to fix this, looking at the code below.
Will be very grateful for any help!
App.jsx
import React, { Component } from 'react';
import { BrowserRouter, Switch, Route, Link } from 'react-router-dom';
import Heroes from './components/Heroes';
import About from './components/About';
class App extends Component {
render() {
return (
<BrowserRouter>
<>
<Header />
<div className="container">
<Switch>
<Route path="/" exact component={Home} />
<Route path="/heroes" component={Heroes} />
<Route path="/about" component={About} />
</Switch>
</div>
</>
</BrowserRouter>
);
}
}
const Header = () => (
<nav>
<div className="container">
<div className="nav-wrapper">
<Link to="/" className="brand-logo">
<i className="material-icons">home</i>
</Link>
<ul id="nav-mobile" className="right hide-on-med-and-down">
<li>
<Link to="/heroes">Heroes</Link>
</li>
<li>
<Link to="/about">About</Link>
</li>
</ul>
</div>
</div>
</nav>
);
const Home = () => (
<>
<h3>Fullstack Express-Apollo-React</h3>
</>
);
export default App;
Heroes.jsx
import React, { Component } from 'react';
import { BrowserRouter, Switch, Route, Link } from "react-router-dom";
import Hero from './Hero';
const mockData = {
"heroes": [
{
"_id": "5db31d0c5419031a7c8d749c",
"title": "qqqqqqqqqqqqqqq",
"description": "ljlkjlkjlkj",
"date": "1572019076651"
},
{
"_id": "5db331e25419031a7c8d749d",
"title": "gfdgfdhgfdhgfdgf",
"description": "yuytruytrytryt",
"date": "1572019076651"
},
{
"_id": "5db332405419031a7c8d749e",
"title": "mnbvmnbvmnbvnbvmn",
"description": "eytretretretretr",
"date": "1572019076651"
}
]
}
class Heroes extends Component {
render() {
return (
<div>
<BrowserRouter>
<Switch>
{mockData.heroes.map(hero => (
<Route
exact
path={`/heroes/${hero._id}`}
render={() => <Hero data={hero} />}
/>
))}
<Route
exact
path="/heroes"
component={Home}
/>
</Switch>
</BrowserRouter>
</div>
);
}
}
const Home = () => {
return (
<>
{mockData.heroes.map(hero => (
<div key={hero._id}>
<Link to={`/heroes/${hero._id}`}>
<h3>{hero.title}</h3>
</Link>
<h5>{hero.description}</h5>
<h5>{hero.date}</h5>
</div>
))}
</>
);
};
export default Heroes;
Hero.jsx
import React, { Component } from 'react';
class Hero extends Component {
render() {
return (
<>
<h5>{this.props.data.title}</h5>
<h5>{this.props.data.description}</h5>
</>
);
}
}
export default Hero;
If necessary, here is the link to github repository:
react-homework
Thanks in advance!
Your Heroes component has route
<Route
exact
path="/heroes"
component={Home}
/>
that is pointing towards Home component, while in App it is pointing to Heroes <Route path="/heroes" component={Heroes} /> Could be the cause of your issue
import React, { Component } from 'react';
import { BrowserRouter, Switch, Route, Link } from 'react-router-dom';
import About from './components/About';
import Hero from './components/Hero';
const mockData = {
"heroes": [
{
"_id": "5db31d0c5419031a7c8d749c",
"title": "qqqqqqqqqqqqqqq",
"description": "ljlkjlkjlkj",
"date": "1572019076651"
},
{
"_id": "5db331e25419031a7c8d749d",
"title": "gfdgfdhgfdhgfdgf",
"description": "yuytruytrytryt",
"date": "1572019076651"
},
{
"_id": "5db332405419031a7c8d749e",
"title": "mnbvmnbvmnbvnbvmn",
"description": "eytretretretretr",
"date": "1572019076651"
}
]
}
class App extends Component {
render() {
return (
<BrowserRouter>
<>
<Header />
<div className="container">
<Switch>
<Route path="/" exact component={Home} />
{mockData.heroes.map(hero => (
<Route
exact
path={`/heroes/${hero._id}`}
render={() => <Hero data={hero} />}
/>
))}
<Route
exact
path="/heroes"
component={heroesIndex}
/>
<Route path="/about" component={About} />
</Switch>
</div>
</>
</BrowserRouter>
);
}
}
const Header = () => (
<nav>
<div className="container">
<div className="nav-wrapper">
<Link to="/" className="brand-logo">
<i className="material-icons">home</i>
</Link>
<ul id="nav-mobile" className="right hide-on-med-and-down">
<li>
<Link to="/heroes">Heroes</Link>
</li>
<li>
<Link to="/about">About</Link>
</li>
</ul>
</div>
</div>
</nav>
);
const heroesIndex = () => {
return (
<>
{mockData.heroes.map(hero => (
<div key={hero._id}>
<Link to={`/heroes/${hero._id}`}>
<h3>{hero.title}</h3>
</Link>
<h5>{hero.description}</h5>
<h5>{hero.date}</h5>
</div>
))}
</>
);
};
const Home = () => (
<>
<h3>Fullstack Express-Apollo-React</h3>
</>
);
export default App;

Why React Router only works with stateless component?

I'm trying the simplest code to understand the React Router.
I brought the example of the site: "https://reacttraining.com/react-router/web/example/basic" and only changed one thing, the component 'About'.
import React from 'react'
import ReactDOM from 'react-dom'
import registerServiceWorker from './registerServiceWorker'
import {
BrowserRouter as Router,
Route,
Link
} from 'react-router-dom'
const BasicExample = () => (
<Router>
<div>
<ul>
<li><Link to="/">Home</Link></li>
<li><Link to="/about">About</Link></li>
<li><Link to="/topics">Topics</Link></li>
</ul>
<hr/>
<Route exact path="/" component={Home}/>
<Route path="/about/:aaa" component={About}/>
<Route path="/topics" component={Topics}/>
</div>
</Router>
)
const Home = () => (
<div>
<h2>Home</h2>
</div>
)
class About extends React.Component {
render() {
return (
<div>
<h2>About</h2>
</div>
);
}
}
const Topics = ({ match }) => (
<div>
<h2>Topics</h2>
<ul>
<li>
<Link to={`${match.url}/rendering`}>
Rendering with React
</Link>
</li>
<li>
<Link to={`${match.url}/components`}>
Components
</Link>
</li>
<li>
<Link to={`${match.url}/props-v-state`}>
Props v. State
</Link>
</li>
</ul>
<Route path={`${match.url}/:topicId`} component={Topic}/>
<Route exact path={match.url} render={() => (
<h3>Please select a topic.</h3>
)}/>
</div>
)
console.log('Topics', Topics);
const Topic = ({ match }) => (
<div>
<h3>{match.params.topicId}</h3>
</div>
)
export default BasicExample
ReactDOM.render(<BasicExample />, document.getElementById('root'));
registerServiceWorker();
If i use:
class About extends React.Component {
render() {
return (
<div>
<h2>About</h2>
</div>
);
}
}
React-router do not show this component. and why i want to use this? because with this i can use State.
Now i'm reading this article: https://hackernoon.com/react-stateless-functional-components-nine-wins-you-might-have-overlooked-997b0d933dbc
Maybe i will find the answer there. then i will come and edit...

Categories

Resources