I have a personal project I'm working on and I have run into a bit of a problem. I have two simple code snippets one for the component and one for handling the route.
import { Routes, Route } from "react-router-dom";
function setPath {
return (
<Routes>
<Route path="/sect/guest" element={<MobileCardsGuest />} />
<Routes/>
)
} ```
the setPath component is called in App.js
component to be displayed
import React from "react";
import eventIcon from "../../assets/img/red-carpet.png";
import mealIcon from "../../assets/img/hamburger.png";
import accIcon from "../../assets/img/accomodation.png";
import "../../assets/css/mobilecards.css";
import { Link } from "react-router-dom";
import { toast } from "react-toastify";
function MobileCardsGuest() {
const notify = ()=>{
return toast.info("Coming Soon")
}
return (
<div className="mobile-card">
<p className="text-center mob-title">
<b style={{ color: "var(--pieme-color)" }}>You are Welcome</b>
</p>
<p className="text-center mob-body">Please choose what you would like</p>
<div class="card bg-light m-card">
<p></p>
<img src={mealIcon} className="iconimg" alt="Meal Icon"/>
<div class="card-body text-center">
<p class="card-text">Meal</p>
</div>
</div>
<div class="card bg-light m-card">
<p></p>
<img src={accIcon} className="iconimg" alt="Acc Icon" />
<div class="card-body text-center">
<p class="card-text">Accomodation</p>
</div>
</Link>
</div>
<div class="card bg-light m-card" onClick={notify}>
<p></p>
<img src={eventIcon} className="iconimg" alt="Event Icon"/>
<div class="card-body text-center">
<p class="card-text">Event</p>
</div>
</div>
</div>
);
}
export default MobileCardsGuest;
the other component
import useNavigate from "react-router-dom"
const navigate= useNavigate();
function Navbar{
return (
<button onClick={() => {navigate("/sect/guest")>
Guest
</button>
)
}
When I run the above and go to the path"/sect/guest"` it doesn't display the component.
If you are using react 18 or latest react-router-dom then your routes structure would be like :
<Router>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/cart" element={<Cart />} />
</Routes>
<Router>
Here BrowserRouter and switch will not beused in newer version applications.
You need to import BrowserRouter as well.
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import MobileCardsGuest from './path/MobileCardsGuest';
const SetPath = () => {
return (
<BrowserRouter>
<Routes>
<Route exact path='/sect/guest' element={<MobileCardsGuest />} />
</Routes>
... ...
</BrowserRouter>
);
}
export default SetPath;
Related
I try to make a route of Register and Login components inside a div(className='container') in react-router v6, but when i try to access these components I reach a blank page, then when i rid the div class it works very well, i don't know if the problem from the div. please help me to fix it:
this is my code:
enter code here
import './App.css';
import Navbar from './components/layout/Navbar';
import Footer from './components/layout/Footer';
import Landing from './components/layout/Landing';
import {BrowserRouter as Router, Outlet, Routes, Route} from "react-router-dom";
import Register from "./components/auth/Register";
import Login from "./components/auth/Login";
function App() {
return (
<Router >
<div className="App">
<Navbar />
<Routes>
<Route path="/" element={<Landing />} />
<div className="container">
<Route path="/register" element={<Register />} />
<Route path="/login" element={<Login />} />
</div>
</Routes>
<Footer />
</div>
</Router>
);
}
export default App;
import React, { Component } from 'react';
import {Outlet} from 'react-router-dom';
class Register extends Component {
render() {
return (
<div >
<h1>Register</h1>
</div>
)
}
}
export default Register;
import React, { Component } from 'react';
import {Outlet} from 'react-router-dom';
class Login extends Component {
render() {
return (
<div>
<h2>Login</h2>
</div>
)
}
}
export default Login;
import React, { Component } from 'react';
import { Link, Outlet } from "react-router-dom";
class Landing extends Component {
render() {
return (
<div className="landing">
<div className="dark-overlay landing-inner text-light">
<div className="container">
<div className="row">
<div className="col-md-12 text-center">
<h1 className="display-3 mb-4">Developer Connector
</h1>
<p className="lead"> Create a developer profile/portfolio, share posts and get help from other developers</p>
<hr />
<Link to="/register" className="btn btn-lg btn-info mr-2">Sign Up</Link>
<Link to="/login" className="btn btn-lg btn-light">Login</Link>
</div>
</div>
</div>
</div>
</div>
)
}
};
export default Landing;
When you try to put a DIV object as a route, the problem occurs.
I suggest you remove the DIV from the APP component and put it inside each page (register, login) as needed.
Wish you the best!
import './App.css';
import Navbar from './components/layout/Navbar';
import Footer from './components/layout/Footer';
import Landing from './components/layout/Landing';
import {BrowserRouter as Router, Outlet, Routes, Route} from "react-router-dom";
import Register from "./components/auth/Register";
import Login from "./components/auth/Login";
function App() {
return (
<Router >
<div className="App">
<Navbar />
<Routes>
<Route path="/" element={<Landing />} />
<Route path="/register" element={<Register />} />
<Route path="/login" element={<Login />} />
</Routes>
<Footer />
</div>
</Router>
);
}
export default App;
Don't use div inside Routes. Use Route with some custom components.
I am reusing this component from another project, and I can't figure out why it doesn't work in this one despite working in the other one.
It should check if the user has a token in their cookies, and then redirect to the homepage if they don't. If they do, they should see the component.
I'm not receiving any errors. The page always redirects to the homepage.
ProtectedRoutes.js
import React from "react";
import { Navigate } from "react-router-dom";
import Cookies from "universal-cookie";
const cookies = new Cookies();
export default function ProtectedRoutes({component: Component, ...rest}) {
//get the cookie if there is one
const token = cookies.get("TOKEN");
//if there is a valid cookie, show component, otherwise go to homepage
return token ? <Component /> : <Navigate to="/" />
}
App.js
import './App.css';
import React from 'react';
import {BrowserRouter, Routes, Route, Link} from 'react-router-dom';
import HomeScreen from './Components/HomeScreen';
import LoginScreen from './Components/LoginScreen';
import RegisterScreen from './Components/RegisterScreen';
import AccountScreen from './Components/AccountScreen';
import PreferencesScreen from './Components/PreferencesScreen';
import ProtectedRoutes from './Components/ProtectedRoutes';
import Cookies from 'universal-cookie';
const cookies = new Cookies();
function App() {
const openMenu = () => {
document.querySelector(".sidebar").classList.add("open");
}
const closeMenu = () => {
document.querySelector(".sidebar").classList.remove("open");
}
const logout = (e) => {
e.preventDefault();
cookies.remove("TOKEN", {path: "/"});
window.location.href="/"
}
return (
<BrowserRouter>
<div className="container">
<header className="header">
<div className="brand">
<button className="sidebar-button" onClick={openMenu}>
☰
</button>
<Link to="/" >Title</Link>
</div>
<div className="header-links">
<Link to="/signin" >Sign In</Link>
<Link to="/myaccount/" >My Account</Link>
<Link to="/logout" onClick={(e) => logout()}>Logout</Link>
</div>
</header>
<aside className="sidebar">
<button className="sidebar-close-button" onClick={closeMenu}>x</button>
<div className="sidebar-links">
<h4>New Entry</h4>
<h4>New Entry</h4>
</div>
</aside>
<main className="main">
<div className="content">
<Routes>
<Route exact path="/" element={<HomeScreen />} />
<Route exact path="/register" element={<RegisterScreen />} />
<Route exact path="/signin" element={<LoginScreen />} />
<Route exact path="/myaccount" element={<ProtectedRoutes component={AccountScreen} />} />
<Route exact path="/preferences" element={<PreferencesScreen />} />
</Routes>
</div>
</main>
</div>
</BrowserRouter>
);
}
export default App;
Everything works fine. Content changes after pressing NavLink, but when I reload the page, the content disappears. Аlthough, interestingly, the URL remains the same. How to fix, or so it should be?
*Before reloading *
*After reloading *
Code:
App.js:
import React from 'react'
import './App.css';
import Header from './components/Header/Header';
import Nav from './components/Nav/Nav';
import Profile from './components/Profile/Profile.jsx';
import Dialog from './components/Dialog/Dialog'
import { BrowserRouter, Route } from 'react-router-dom';
const App = () => {
return (
<BrowserRouter>
<div className="App">
<Header />
<Nav />
<Route path='/profile' component={Profile} />
<Route path='/dialog' component={Dialog} />
</div>
</BrowserRouter>
);
}
export default App;
Dialog.jsx:
import React from 'react'
import style from './Dialog.module.css'
import MessageOleg from '../Messages/MessageOleg'
import MessageMax from '../Messages/MessageMax'
import { BrowserRouter, Route, NavLink } from 'react-router-dom'
const Dialog = () => {
return (
<BrowserRouter>
<div className={style.dialog}>
<div className={style.users}>
<div className={style.user}> <NavLink to='/messageOleg'> Oleg </NavLink> </div><br />
<div className={style.user}> <NavLink to='/messageMax' >Max </NavLink> </div><br />
<div className={style.user}> Nata </div><br />
<div className={style.user}> Fuflo </div><br />
<div className={style.user}> Kiko </div><br />
</div>
<hr />
<Route path='/messageOleg' component={MessageOleg} />
<Route path='/messageMax' component={MessageMax} />
</div>
</BrowserRouter>
)
}
export default Dialog;
MessageOleg.jsx:
import React from 'react'
import style from './MessageOleg.module.css'
const MessageOleg = () => {
return (
<div className={style.messages}>
<div className={style.message}>
Hey
</div>
</div>
)
}
export default MessageOleg;
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>
I have a hook that changes the background color of my app. I would like the background color to stay changed when navigating through the site, but the Router resets this state back to its original useState of 'white'. How do I implement this correctly?
Created with create-react-app.
Edited to show minimum reproducible example:
import React, { useState } from 'react';
import { Route, Switch, BrowserRouter } from 'react-router-dom';
import './App.css';
export default function App() {
const [color, setColor] = useState('white');
function changeBackground(value) {
setColor(value);
};
return (
<div className={color}>
<BrowserRouter>
<Navbar changeBackground={changeBackground} />
</BrowserRouter>
</div>
);
};
function Navbar(props) {
return (
<div>
<button onClick={() => props.changeBackground('red')}>
Change Background Color
</button>
<div>
Page 1
</div>
<div>
Page2
</div>
<Switch>
<Route exact path="/page1"><Page1 /></Route>
<Route exact path="/page2"><Page2 /></Route>
</Switch>
</div>
);
};
function Page1() {
return (
<div>
Page 1
</div>
);
};
function Page2() {
return (
<div>
Page 2
</div>
);
};
/* App.css */
.white {
background-color: white;
}
.red {
background-color: red;
}
Previous code before adding minimum reproducible example:
import React, { useState } from 'react';
import { Route, Switch, BrowserRouter } from 'react-router-dom';
import './App.css';
import './assets/fonts/fonts.css';
import Navbar from './components/Navbar';
import Design from './components/Design';
import Develop from './components/Develop';
import Else from './components/Else';
import DesignTest from './pages/DesignTest';
function App() {
const [backgroundColor, setBackgroundColor] = useState('white');
function changeBackground(value) {
setBackgroundColor(value);
};
return (
<div className={`w-screen min-h-screen ${backgroundColor}`}>
{/* <Router> */}
<Navbar changeBackground={changeBackground} />
<BrowserRouter>
<Switch>
<Route exact path="/"></Route>
<Route exact path="/design"><Design /></Route>
<Route exact path="/develop"><Develop /></Route>
<Route exact path="/else"><Else /></Route>
<Route exact path="/design/test"><DesignTest /></Route>
</Switch>
</BrowserRouter>
</div>
);
}
export default App;
function Navbar(props) {
return (
<div className="w-screen h-screen inline-grid grid-cols-12 grid-rows-6 tuffyBold tracking-widest">
<div className="row-start-1 row-end-3 col-start-1 col-end-7 text-right mt-auto mb-auto text-5xl">
TITLE
</div>
<div className="row-start-3 row-end-4 col-start-7 col-end-13 test-left mt-auto mb-auto text-4xl">
<a href="/design">
DESIGN
</a>
</div>
<div className="row-start-4 row-end-5 col-start-7 col-end-13 test-left mt-auto mb-auto text-4xl">
<a href="/develop">
DEVELOP
</a>
</div>
<div className="row-start-5 row-end-7 col-start-7 col-end-13 test-left mt-auto mb-auto text-4xl">
<a href="/else">
EVERY<br />THING<br />ELSE
</a>
</div>
<div className="row-start-1 row-end-3 col-start-7 col-end-13 mt-auto mb-auto ml-auto mr-auto">
<div className="circle white" onClick={() => props.changeBackground('white')}></div>
</div>
<div className="row-start-3 row-end-4 col-start-1 col-end-7 mt-auto mb-auto ml-auto mr-auto">
<div className="circle yellow" onClick={() => props.changeBackground('yellow')}></div>
</div>
<div className="row-start-4 row-end-5 col-start-1 col-end-7 mt-auto mb-auto ml-auto mr-auto">
<div className="circle blue" onClick={() => props.changeBackground('blue')}></div>
</div>
<div className="row-start-5 row-end-6 col-start-1 col-end-7 mt-auto mb-auto ml-auto mr-auto">
<div className="circle dark" onClick={() => props.changeBackground('dark')}></div>
</div>
</div>
);
}
export default Navbar;
.yellow {
background-color: #CDB900;
color: black;
}
.blue {
background-color: #009CCD;
color: black;
}
.dark {
background-color: #4B394E;
color: white;
}
.white {
background-color: white;
color: black;
}
I found my issue. I was using <a href="/#"> instead of importing Link from react-router-dom, causing the entire page to re-render. Here is the version that worked as I intended:
import React, { useState } from 'react';
import { Route, Switch, BrowserRouter, Link } from 'react-router-dom';
import './App.css';
export default function App() {
const [color, setColor] = useState('white');
function changeBackground(value) {
setColor(value);
};
return (
<div className={color}>
<BrowserRouter>
<Navbar changeBackground={changeBackground} />
</BrowserRouter>
</div>
);
};
function Navbar(props) {
return (
<div>
<button onClick={() => props.changeBackground('red')}>
Change Background Color
</button>
<div>
<Link to="/page1">Page 1</Link>
</div>
<div>
<Link to="/page2">Page2</Link>
</div>
<Switch>
<Route exact path="/page1"><Page1 /></Route>
<Route exact path="/page2"><Page2 /></Route>
</Switch>
</div>
);
};
function Page1() {
return (
<div>
Page 1
</div>
);
};
function Page2() {
return (
<div>
Page 2
</div>
);
};
/* App.css */
.white {
background-color: white;
}
.red {
background-color: red;
}
I had the same issue of complete app state refresh as I click on the navbar for a route change. It turned out that the issue was due to not using Link component provided by react router.
In my case I was using bootstrap navbar components. The code that I got from bootstrap site creates navbar link like this:
<Nav.Link href="/home">Home</Nav.Link>
This navigation through 'href' is the problem here. So in order to overcome this issue I wrapped Nav.Link inside LinkContainer. This allowed me to remove href from Nav.Link and I provided the route url using 'to' property in LinkContainer.
<LinkContainer to="/home">
<Nav.Link>Home</Nav.Link>
</LinkContainer>
In order to use LinkContainer I had to install and import it.
npm install react-router-bootstrap
import { LinkContainer } from "react-router-bootstrap";
Because your Navbar is outside the router component, meaning everything you click something it's actually reloading the page instead of being captured by react-router. Move the navbar component inside browser router:
return (
<div className={`w-screen min-h-screen ${backgroundColor}`}>
{/* <Router> */}
<BrowserRouter>
<Navbar changeBackground={changeBackground} />
<Switch>
<Route exact path="/"></Route>
<Route exact path="/design"><Design /></Route>
<Route exact path="/develop"><Develop /></Route>
<Route exact path="/else"><Else /></Route>
<Route exact path="/design/test"><DesignTest /></Route>
</Switch>
</BrowserRouter>
</div>
);
It is seems that something trigger re-render the whole App. Probably React Developer Tools can help you to find that place in code.
I have created an isolated example - https://codesandbox.io/s/solitary-wood-8oi66?fontsize=14&hidenavigation=1&theme=dark&file=/src/App.js
In this example value with color from the hook also saves into the browser LocalStorage, and use as a default value for the first render, so it makes it possible to keep the background color after reloading the page. Maybe this is what you want to achieve. but I'm not sure.
const defaultColor = localStorage.getItem("bgColor");
const [backgroundColor, setBackgroundColor] = useState(
defaultColor || "white"
);
function changeBackground(value) {
setBackgroundColor(value);
localStorage.setItem("bgColor", value);
}