home navlinks link stay active REACT - reactjs

I hoe you are doing well :)
when I click on a link from the navbar, the home link is always active. I tried to add excat to the home route but nothing changed?
if someone can help me please that would be great.
thank you in advance
thank you for your time
import { NavLink } from "react-router-dom";
import { links } from "../utils/constants";
import styled from "styled-components";
const NavMenu = () => {
return (
<Nav>
<ul>
{links.map((link) => {
const { id, url, text } = link;
return (
<li key={id}>
<NavLink to={url}>{text}</NavLink>
</li>
);
})}
</ul>
</Nav>
);
};
const Nav = styled.nav`
////////
.active {
color: var(--white);
}
}
`;
export default NavMenu;
APP.js
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
import { NavMenu } from "./components";
import { Home, About, Projects, Contact, Error } from "./pages";
const App = () => {
return (
<Router>
<NavMenu />
<Switch>
<Route exact path="/">
<Home />
</Route>
<Route exact path="/about">
<About />
</Route>
<Route exact path="/projects">
<Projects />
</Route>
<Route exact path="/contact">
<Contact />
</Route>
<Route path="*">
<Error />
</Route>
</Switch>
</Router>
);
};
export default App;

I think you are not using Route Component properly. You should try in this way.
Pass the path and component in the Route instead of wrapping it inside in Route component.
import { HomePage, UserPage } from "./pages";
const routes = [
{
path: '/home',
component: HomePage,
},
{
path: '/user',
component: UserPage,
}]
<Switch>
{routes.map(({ path, component }, index) => (
<Route key={String(index)} exact path={path} component={component} />
))}
</Switch>

Related

No component is being displayed in my reactjs app

I am trying to build a website using ReactJS. Currently, I have a home page and a navbar. None of these components are displayed when trying to view them inside the browser. I guess the problem sits inside of my router, but i can't really put my finger on it.
These are the two components/pages I want to display:
Home.tsx
import Background from "../components/Background";
export default function Home() {
return (
<div>
<Background />
<h1>Testing text</h1>
</div>
);
}
Navbar.tsx
import Link, { LinkProps } from "../components/Link";
const navElements: LinkProps[] = [
{
label: "Configure",
to: "/Configure",
},
{
label: "Archive",
to: "/Archive",
},
{
label: "About",
to: "/About",
},
{
label: "Contact",
to: "/Contact",
},
];
export default function Navbar() {
return (
<div className="flex font-serif space-x-4">
{navElements.map((navElement) => (
<Link {...navElement} key={navElement.label} />
))}
</div>
);
}
These components are brought together in the Routing.tsx:
import { Route, Routes, BrowserRouter, Outlet } from "react-router-dom";
import Home from "../pages/Home";
import Navbar from "../layout/Navbar";
export default function Routing() {
return (
<BrowserRouter>
<Routes>
<Route
element={
<>
<Navbar />
<Outlet />
</>
}
/>
<Route path="home">
<Route index element={<Home />}></Route>
</Route>
</Routes>
</BrowserRouter>
);
}
The router is finally put into App.tsx
According to the docs, index routes are displayed on parent element's Outlet component.
In your case parent route doesn't have any element. change into this.
<Route path="home" element={<Home />}>
//add any index route with element if you want
</Route>
After some trial and error (including #Arjun's answer) it worked with the following line of code (part of Routing.tsx):
<BrowserRouter>
<Routes>
<Route
element={
<>
<Navbar />
<Outlet />
</>
}
>
<Route index element={<Home />} />
</Route>
</Routes>
</BrowserRouter>
);
}

Warning: Maximum update depth exceeded. This can happen when a component calls setState inside useEffect,

evtools_backend.js:4026 Warning: Maximum update depth exceeded. This can happen when a component calls setState inside useEffect, but useEffect either doesn't have a dependency array, or one of the dependencies changes on every render.
this is my code
import React, { useState } from 'react';
import Home from './Home'
import About from './About'
import Blog from './Blog'
import Contact from './Contact'
import { BrowserRouter, Routes, Route, Link, Navigate } from 'react-router-dom'
import SpeechRecognition, { useSpeechRecognition } from 'react-speech-recognition'
const App = () => {
const commands = [
{
command: ['Goto *', 'Open *'],
callback: (navigatePage) => setNavigateUrl(navigatePage)
}
]
const {transcript} = useSpeechRecognition({commands});
const [ navigateUrl, setNavigateUrl ] = useState("");
const pages = ['home', 'about', 'blog', 'contact'];
const urls = {
home: '/',
about: '/about',
blog: '/blog',
contact: '/contact'
}
if(!SpeechRecognition.browserSupportsSpeechRecognition) {
return <h1>browser doesn't support</h1>;
}
let navigate= "";
if(navigateUrl) {
if(pages.includes(navigateUrl)) {
navigate = <Navigate to={urls[navigateUrl]} />;
console.log('error', navigate);
} else {
navigate = <p>page could not find: {navigateUrl}</p>;
}
}
return (
<div className="App">
<BrowserRouter>
<div id="links">
<Link to='/'>Home</Link>
<Link to='/about'>About</Link>
<Link to='/blog'>Blog</Link>
<Link to='/contact'>Contact</Link>
</div>
<Routes>
<Route path='/' exact element={<Home />} />
<Route path='/home' element={<Home />} />
<Route path='/about' element={<About />} />
<Route path='/blog' element={<Blog />} />
<Route path='/contact' element={<Contact />} />
</Routes>
</BrowserRouter>
<p id="transcript">Transcipt: {transcript}</p>
<p>Only use goto or open the 'page name'</p>
<button onClick={SpeechRecognition.startListening}>Start</button>
</div>
);
}
export default App;
i tried as far as i can expand.

My react onClick navigate shows URL, but does not render component

I am new to React router here and I am trying to make clicking on a recipe in my 'BrowseRecipes' page redirect to a page dedicated to that recipe. However, when I click on the recipe, the URL shows the correct URL /browse/${recipeID}, but the page I assign to this route does not render. Only the /browse page with a list of all the recipes renders. Does anyone know why?
Here is my APP.js
import AddNewRecipe from './components/AddNewRecipe'
import BrowseRecipes from './components/BrowseRecipes'
import { currentState } from './components/redux';
import ReactDOM from 'react-dom'
import { BrowserRouter as Router, Switch, Route, Routes, Link, useParams} from "react-router-dom";
import AuthReqPage from "./components/AuthReqPage"
import Navbar from "./components/Navbar"
import RecipePage from "./components/BrowseRecipes/RecipePage"
import PageNotFound from "./components/PageNotFound"
function App(props) {
return (
<Router>
<div className="App">
<Navbar />
<Routes>
<Route path='/add' element={<AddNewRecipe />} />
<Route path='/' element={<BrowseRecipes />} />
<Route path='/browse' element={<BrowseRecipes />}>
<Route path=':recipeID' element={<RecipePage />}/>
</Route>
<Route path='/authrequired' element={<AuthReqPage />} />
<Route path='/*' element={<PageNotFound />} />
</Routes>
</div>
</Router>
);
}
export default App;
Here is my BrowseRecipe component/page:
export function BrowseRecipes (props){
console.log('browseRecipe running')
let navigate = useNavigate()
let params=useParams()
console.log(params.recipeID)
if(props.recipeStore.length>0)
{
var displayRecipes = props.recipeStore.map(
elem=>
{
return (<li key={elem.recipeID} className='recipeDisplayBox' onClick={()=>navigate(`/browse/${elem.recipeID}`)}>
{elem.title},
Prep: {elem.prepTime.numeral} {elem.prepTime.unit}
</li>)
}
)
}
return(
<div>
<h1>Browse Recipes</h1>
<h2>Your recipes:</h2>
<ul>
{displayRecipes}
</ul>
</div>
)
}
const mapStateToProps=(state)=>{
return {recipeStore: state.recipe}}
export default connect(mapStateToProps)(RequireAuth(BrowseRecipes))
And here is the individual recipe page that failed to render:
export function RecipePage (props){
console.log('RecipePage running')
let params=useParams()
return(
<div>
<h1>{params.recipeID}</h1>
</div>
)
}
const mapStateToProps=(state)=>{
return {recipeStore: state.recipe}}
export default connect(mapStateToProps)(RequireAuth(RecipePage))
"RequireAuth" here is a higher-order component that redirects the page to 'Please Sign In' page if the user is not signed in.
Did I misunderstand something about the use of UseParams? Please help me shed some light! Thank you very much
You've rendered the RecipePage component on a nested route from the "/browse" route rendering the BrowseRecipes component.
<Route path='/browse' element={<BrowseRecipes />}>
<Route path=':recipeID' element={<RecipePage />}/>
</Route>
In this configuration the BrowseRecipes is required to render an Outlet component for the nested routes to be rendered into.
Example:
import { Outlet, useNavigate, useParams } from 'react-router-dom';
export function BrowseRecipes (props) {
const navigate = useNavigate();
const params = useParams();
let displayRecipes;
if (props.recipeStore.length) {
displayRecipes = props.recipeStore.map(elem => {
return (
<li
key={elem.recipeID}
className='recipeDisplayBox'
onClick={() => navigate(`/browse/${elem.recipeID}`)}
>
{elem.title},
Prep: {elem.prepTime.numeral} {elem.prepTime.unit}
</li>
);
});
}
return (
<div>
<h1>Browse Recipes</h1>
<h2>Your recipes:</h2>
<ul>
{displayRecipes}
</ul>
<Outlet /> // <-- nested routes render here
</div>
);
}
If you don't want to render both BrowseRecipes and RecipePage at the same time, then create a nested index route specifically for BrowseRecipes.
Example:
<Route path='/browse'>
<Route index element={<BrowseRecipes />} /> // <-- "/browse"
<Route path=':recipeID' element={<RecipePage />} /> // <-- "/browse/:recipeID"
</Route>
For more information, see:
Index Routes
Layout Routes

How can i protect routes in my reactjs project?

i need help to protect routes in my reactjs project , i want that only a loged user can access to Home Page, and only not loged user can access to the signin and signup forms
import "./App.css";
import { BrowserRouter, Route, Routes } from "react-router-dom";
import Navbar from "./components/Navbar";
import SignInForm from "./pages/SignInForm";
import SignUpForm from "./pages/SignUpForm";
import Wallet from "./components/Wallet";
import Welcome from "./pages/Welcome";
import Home from "./pages/Home";
function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<Welcome></Welcome>}></Route>
<Route path="/signin" element={<Navbar></Navbar>}>
<Route index element={<SignInForm></SignInForm>}></Route>
</Route>
<Route path="/signup" element={<Navbar></Navbar>}>
<Route index element={<SignUpForm></SignUpForm>}></Route>
</Route>
<Route path="/wallet" element={<Navbar></Navbar>}>
<Route index element={<Wallet></Wallet>}></Route>
</Route>
<Route path="/home" element={<Navbar></Navbar>}>
<Route index element={<Home></Home>}></Route>
</Route>
</Routes>
</BrowserRouter>
);
}
export default App;
This is how I did it, basically, you wrap the route and check if the user is authenticated, if he's not, redirect back to where he should be.
This uses react-router v6, you can find more information about it in the authentication section of the official docs. They have a very good example on stackblitz, you should take a look at that.
import { useIsAuthenticated } from "your-auth-package"
import { Navigate, useLocation } from "react-router";
const AuthenticatedRoute = ({ children }) => {
const isAuthenticated = useIsAuthenticated();
const location = useLocation();
// not logged in
if (!isAuthenticated) {
console.log("not authenticated");
return <Navigate to="/" state={{ from: location }} replace />;
}
return children;
};
<BrowserRouter>
<Routes>
<Route
path="/dashboard"
element={
<AuthenticatedRoute>
<Dashboard />
</AuthenticatedRoute>
}
/>
</Routes>
</BrowserRouter>
Make a component like below and adjust it to your requirement.
import React from "react";
import { Redirect, Route } from "react-router-dom";
import auth from "../services/authService";
function ProtectedRoute({ path, component: Component, render, ...rest }) {
return (
<Route
{...rest}
render={(props) => {
if (!auth.getCurrentUser())
return (
<Redirect
to={{
pathname: "/login",
state: { from: props.location },
}}
/>
);
return Component ? <Component {...props} /> : render(props);
}}
/>
);
}
export default ProtectedRoute;
then wrap the route like this
<ProtectedRoute path="/wallet" element={<Navbar></Navbar>}/>

Getting 404 in GitHub Pages on redirection

I'm trying to learn how to use GitHub Pages with a basic React project. But I'm having an issue with the URL of the different pages of the project (like /home /about...).
I have a GH Page here: https://naacho20.github.io/itis/
If u try to use the navbar, a 404 would appear, but thats wrong because I have a Router redirecting that. I show my code so I can explain better:
App.js:
import "bootstrap/dist/css/bootstrap.min.css";
import "./App.css";
import { BrowserRouter, Route } from "react-router-dom";
import Navbar from "./components/Navbar";
import Home from "./pages/Home";
import About from "./pages/About";
import Portfolio from "./pages/Portfolio";
import Contact from "./pages/Contact";
export default function App() {
return (
<div>
<BrowserRouter>
<Navbar />
<Route exact path="/" component={Home} />
<Route path="/about" component={About} />
<Route path="/portfolio" component={Portfolio} />
<Route path="/contact" component={Contact} />
</BrowserRouter>
</div>
);
}
Contact.js
import React from "react";
export default function Contact() {
return <div>Contact</div>;
}
Navbar.js
import React from "react";
import { withRouter } from "react-router-dom";
import { Navbar, Nav } from "react-bootstrap";
const menuItems = [
{
to: "/",
title: "Inicio",
},
{
to: "/about",
title: "Sobre mí",
},
{
to: "/portfolio",
title: "Portfolio",
},
{
to: "/contact",
title: "Contacto",
},
];
class NavBar extends React.Component {
getNavLinkClass = (path) => {
return this.props.location.pathname === path ? "active" : "";
};
render() {
return (
<div>
<Navbar bg="dark" expand="lg" variant="dark">
<Navbar.Brand href="/">IT.IS</Navbar.Brand>
<Navbar.Toggle aria-controls="basic-navbar-nav" />
<Navbar.Collapse id="basic-navbar-nav">
<Nav className="ml-auto">
{menuItems.map((item, index) => {
return (
<Nav.Link
key={index}
className={this.getNavLinkClass(item.to)}
href={item.to}
>
{item.title}
</Nav.Link>
);
})}
</Nav>
</Navbar.Collapse>
</Navbar>
</div>
);
}
}
NavBar = withRouter(NavBar);
export default NavBar;
So I see thats a problem from the URL, I see when I start the app, this goes to localhost:3000/itis and the Home page don't render, but if I remove the itis (localhost:3000/) it render the Home Page. I don't know what I'm doing wrong, any suggestion?
Ty.
This is because you are using SPA app so your all routes serving from one html file. You should use HashRouter to fix it. It is so simple you should import HashRouter instead of
BrowserRouter
import { BrowserRouter} from "react-router-dom";
to
import { HashRouter } from "react-router-dom";
and wrap it with your App
Also you have to wrap your Routes with Switch like this
<BrowserRouter>
<Switch>
<Navbar />
<Route exact path="/" component={Home} />
<Route path="/about" component={About} />
<Route path="/portfolio" component={Portfolio} />
<Route path="/contact" component={Contact} />
</Switch>
</BrowserRouter>

Resources