I'm getting a blank screen with React JS Navigation - javascript

I've read some other articles about people facing the same issue but still haven't found anything that works for me. What has me confused is that the Login.js code works when I run it directly without navigation. Likewise, if I change the Login.js code and merely render an H1 tag, it works even with navigation.
AppRouter.js
class AppRouter extends Component {
render() {
return (
<BrowserRouter>
<div>
<Navigation />
<Routes>
<Route exact path="/" element={<Home/>}/>
<Route exact path="/login" element={<Login/>}/>
<Route component={Error}/>
</Routes>
</div>
</BrowserRouter>
);
}
}
export default AppRouter;
Navigation.js
import React from 'react';
import { NavLink } from 'react-router-dom';
const Navigation = () => {
return (
<div>
<NavLink to="/">Home</NavLink>
<NavLink to="/login">Login</NavLink>
</div>
);
}
export default Navigation;
Login.js
export default function Login(){
{
return (
<>
<Header/>
<Flex
minH={'100vh'}
align={'center'}
justify={'center'}
bg={useColorModeValue('gray.50', 'gray.800')}>
<Stack spacing={8} mx={'auto'} maxW={'lg'} py={12} px={8}>
<Stack align={'center'}>
<Heading fontSize={'4xl'}>Sign in to your account</Heading>
<Text fontSize={'lg'} color={'gray.600'}>
Welcome!<Link color={'blue.400'}>features</Link>
</Text>
</Stack>
<Box
rounded={'lg'}
bg={useColorModeValue('white', 'gray.700')}
boxShadow={'lg'}
p={8}>
<Stack spacing={4}>
<FormControl id="email">
<FormLabel>Email address</FormLabel>
<Input type="email" />
</FormControl>
<FormControl id="password">
<FormLabel>Password</FormLabel>
<Input type="password" />
</FormControl>
<Stack spacing={10}>
<Stack
direction={{ base: 'column', sm: 'row' }}
align={'start'}
justify={'space-between'}>
<Checkbox>Remember me</Checkbox>
<Link color={'blue.400'}>Forgot password?</Link>
</Stack>
<Button
bg={'blue.400'}
color={'white'}
_hover={{
bg: 'blue.500',
}}>
Sign in
</Button>
</Stack>
</Stack>
</Box>
</Stack>
</Flex>
</>
)
}
}
App.js
function App() {
return (
<AppRouter/>
);
}

Try this!
class AppRouter extends Component {
render() {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/login" element={<Login/>}/>
<Route path="/Error" element={<div>Error Message</div>} />
<Route path="*" element={<Navigate to="/Error" />} />
</Routes>
</BrowserRouter>
);
}
}
export default AppRouter;
Codesandbox Example

Related

Uncaught TypeError: Cannot read properties of undefined (reading 'pathname'). How can I solve this issue?

[![enter image description here][1]][1]I'm using all latest version and styled components, This is my App.js file
import { BrowserRouter as Router, Route, Routes } from "react-router-dom";
function App() {
return (
<div className="App">
<GlobalStyle/>
<Router>
<Navbar />
<Routes>
<Route path="/" exact element={<Hero />} />
<Route path="/projects" exact element={<Projects />} />
<Route path="/about" exact element={<About />} />
</Routes>
</Router>
</div>
);
}
Navbar.js
{menuData.map((item, index) => {
const border = index === menuData.length-1 ? '1px solid #fff':'none';
const padding = index === menuData.length-1 ? '0 24px':'0';
return (
<NavItem key={index}>
<NavLinks to={item.link} style={{border, padding}}>
{item.title}
</NavLinks>
</NavItem>
)
})}

navigation in react router dom version 6.3.0 doesn't work proplery

I'm working on react website and I have a problem while navigating to any page
that when I scroll to a certain point in a home page for example then I try to navigate to another page I find the other page is rendered from the the bottom of the page not the top
routes.tsx file
const App: React.FC = () => (
<BrowserRouter>
<Layout className="layout">
<div style={{ marginBottom: "64px" }}>
<Header>
<AppHeader />
</Header>
</div>
<Content>
<div className="site-layout-content">
<Routes>
<Route path="/" element={<Home />} />
<Route path="/offers" element={<Login />} />
<Route path="/aboutUs" element={<AboutUs />} />
<Route path="/contactUs" element={<ContactUs />} />
<Route path="/placeDetails/:id" element={<PlaceDetails />} />
<Route path="/advantages" element={<Advantages />} />
</Routes>
</div>
</Content>
<Footer style={{ textAlign: "center" }}>
<AppFooter />
</Footer>
</Layout>
</BrowserRouter>
);
export default App;
header.tsx
const Index = () => {
const navigate = useNavigate();
return (
<Row className="header">
<Col span={12} className="header__logo">
<div className="header__logo--imgContainer" onClick={() => navigate("/")}>
<img src={logoImg} alt="logo" />
</div>
</Col>
<Col span={12} className="header__menu">
<ul className="ant-menu-overflow ant-menu ant-menu-root ant-menu-horizontal ant-menu-light ant-menu-rtl">
<li className="ant-menu-item">
<span onClick={() => navigate("/offers")}>{strings.header.offers}</span>
</li>
<li className="ant-menu-item">
<span onClick={() => navigate("/advantages")}>{strings.header.services}</span>
</li>
</ul>
</Col>
</Row>
);
};
export default Index;
you can simply use this helper component for this use case:
import { useEffect } from "react";
import { useLocation } from "react-router-dom";
export default function ScrollToTop() {
const { pathname } = useLocation();
useEffect(() => {
// "document.documentElement.scrollTo" is the magic for React Router Dom v6
document.documentElement.scrollTo({
top: 0,
left: 0,
behavior: "instant", // Optional if you want to skip the scrolling animation
});
}, [pathname]);
return null;
}
and then you can change above code like this:
const App: React.FC = () => (
<BrowserRouter>
<ScrollToTop/> // this is new helper component
<Layout className="layout">
<div style={{ marginBottom: "64px" }}>
<Header>
<AppHeader />
</Header>
</div>
<Content>
<div className="site-layout-content">
<Routes>
<Route path="/" element={<Home />} />
<Route path="/offers" element={<Login />} />
<Route path="/aboutUs" element={<AboutUs />} />
<Route path="/contactUs" element={<ContactUs />} />
<Route path="/placeDetails/:id" element={<PlaceDetails />} />
<Route path="/advantages" element={<Advantages />} />
</Routes>
</div>
</Content>
<Footer style={{ textAlign: "center" }}>
<AppFooter />
</Footer>
</Layout>
</BrowserRouter>
);
export default App;
This will reset the scroll position on top whenever route changes.

Making sidebar available for all components | React JS | React Router v6

I am using react router dom v6 and want to implement a logic where the sidebar will be available across all the components in my. Currently whenever i try to click any in side bar the side bar is vanishing.
I want to keep the side bar across all the components in my app.
Side Bar available
Sidebar gone
Index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import {BrowserRouter as Router, Routes, Route,Navigate,Link} from
'react-router-dom'; import Login from
'../src/components/Login/LoginPage'; import Test from
'../src/components/test/Test'; import Homepage from
'../src/components/homepage/HomePage'; import Scheduler from
'../src/components/scheduler/Scheduler'; import Classroom from
'../src/components/classroom/Classroom'; import Assignment from
'../src/components/assignment/Assignment'; import Meeting from
'../src/components/meetings/Meetings'; import ReportCard from
'../src/components/reportcard/ReportCard'; import SideMenuBar from
'../src/components/sidemenubar/SideMenuBar'; ReactDOM.render(
<Router>
<Routes>
<Route path='/' element={<Login />} />
<Route path='/api/v1/testpath' element={<Test />} />
{/* Sidebar Routes */}
<Route path="/api/v1/app/userHome" exact element={<Test />} />
<Route path="/api/v1/app/schedule" exact element={<Scheduler />} />
<Route path="/api/v1/app/myclassroom" exact element={<Classroom />} />
<Route
path="/api/v1/app/myassignments"
exact
element={<Assignment />}
/>
<Route path="/api/v1/app/mymeetings" exact element={<Meeting />} />
<Route path="/api/v1/app/viewreports" exact element={<ReportCard />} />
</Routes>
</Router>,
document.getElementById('root')
);
Sidebar.js
import {
ListItemIcon,
ListItemText,
List,
Divider,
Drawer,
Avatar,
Box,
ListItemButton,
} from "#mui/material";
import { makeStyles } from "#mui/styles";
import HomeIcon from "#mui/icons-material/Home";
import WatchLaterIcon from "#mui/icons-material/WatchLater";
import GroupsIcon from "#mui/icons-material/Groups";
import AssignmentOutlinedIcon from "#mui/icons-material/AssignmentOutlined";
import AssessmentOutlinedIcon from "#mui/icons-material/AssessmentOutlined";
import LogoutOutlinedIcon from "#mui/icons-material/LogoutOutlined";
import MeetingRoomOutlinedIcon from "#mui/icons-material/MeetingRoomOutlined";
import Logo from "./logo.png";
import { BrowserRouter as Router, Route, Link, Routes } from "react-router-dom";
import Homepage from "../homepage/HomePage";
import Scheduler from "../scheduler/Scheduler";
import Classroom from "../classroom/Classroom";
import Assignment from "../assignment/Assignment";
import ReportCard from "../reportcard/ReportCard";
import Meeting from "../meetings/Meetings";
const drawerWidth = 350;
const useStyles = makeStyles({
page: {
background: "#f9f9f9",
width: "100%",
},
root: {
display: "flex",
},
drawer: {
width: drawerWidth,
},
drawerPaper: {
width: drawerWidth,
borderRadius: "2%",
},
listitem: {
"&:hover": {
fontWeight: "fontWeightBold",
background: "#f9f9f9",
},
},
navlink: {
textDecoration: "inherit",
color: "inherit",
},
});
export default function Sidemenubar() {
const classes = useStyles();
return (
<Box sx={{ display: "flex" }}>
<Divider />
<Drawer
className={classes.drawer}
variant="permanent"
classes={{ paper: classes.drawerPaper }}
anchor="left"
>
{/*App Logo */}
<Avatar
src={Logo}
alt="404"
sx={{ width: 100, height: 100, alignSelf: "center", margin: 1 }}
/>
{/*Menu Items */}
<List component="nav">
<Link to="/api/v1/app/userHome" className={classes.navlink}>
<ListItemButton
sx={{
"&:hover": {
fontWeight: "bold",
boxShadow: 1,
background: "#6D62DA",
},
}}
>
<ListItemIcon>
<HomeIcon />
</ListItemIcon>
<ListItemText primary="Home" />
</ListItemButton>
</Link>
<Divider />
<Link to="/api/v1/app/schedule" className={classes.navlink}>
<ListItemButton
sx={{
"&:hover": {
fontWeight: "bold",
boxShadow: 1,
background: "#6D62DA",
},
}}
>
<ListItemIcon>
<WatchLaterIcon />
</ListItemIcon>
<ListItemText primary="Scheduler" />
</ListItemButton>
</Link>
<Divider />
</List>
</Drawer>
<Routes>
<Route path='/api/v1/app/userHome' element={<Homepage />}></Route>
<Route path='/api/v1/app/schedule' element={<Scheduler />}></Route>
</Routes>
</Box>
);
}
HomePage.js
import React from 'react';
import { Grid } from "#mui/material";
import SideMenuBar from '../sidemenubar/SideMenuBar';
import HomePage from '../homepage/HomePage';
import Scheduler from '../scheduler/Scheduler';
import {BrowserRouter as Router,
Routes, Route,Navigate,Link} from 'react-router-dom';
class Test extends React.Component{
render(){
return (
<Grid container>
<Grid item md={4}>
<SideMenuBar />
</Grid>
<Grid item md={8}>
<HomePage />
</Grid>
</Grid>
)
}
}
export default Test;
If you want to render a sidebar on every route/page then I suggest:
Using Layout Wrapper Component and Outlet
Create a layout container component that renders the Sidebar component and an Outlet into the respective grid columns. Render the page routes nested into the layout.
import { Outlet } from 'react-router-dom';
import SideMenuBar from '../sidemenubar/SideMenuBar';
const PageLayout = () => (
<Grid container>
<Grid item md={4}>
<SideMenuBar />
</Grid>
<Grid item md={8}>
<Outlet /> // <-- nested routes rendered here
</Grid>
</Grid>
);
index.js
<Router>
<Routes>
<Route path="/" element={<PageLayout />} >
<Route index element={<Login />} />
<Route path="/api/v1/app/userHome" element={<UserHome />} />
<Route path="/api/v1/app/schedule" element={<Scheduler />} />
<Route path="/api/v1/app/myclassroom" element={<Classroom />} />
<Route
path="/api/v1/app/myassignments"
element={<Assignment />}
/>
<Route path="/api/v1/app/mymeetings" element={<Meeting />} />
<Route path="/api/v1/app/viewreports" element={<ReportCard />} />
</Route>
</Routes>
</Router>
Using Wrapper Component and children Prop
An alternative would be to have the PageLayout component render its children instead, and wrap the Routes component.
const PageLayout = ({ children }) => (
<Grid container>
<Grid item md={4}>
<SideMenuBar />
</Grid>
<Grid item md={8}>
{children}
</Grid>
</Grid>
);
index.js
<Router>
<PageLayout>
<Routes>
<Route path="/ element={<Login />} />
<Route path="/api/v1/app/userHome" element={<UserHome />} />
<Route path="/api/v1/app/schedule" element={<Scheduler />} />
<Route path="/api/v1/app/myclassroom" element={<Classroom />} />
<Route
path="/api/v1/app/myassignments"
element={<Assignment />}
/>
<Route path="/api/v1/app/mymeetings" element={<Meeting />} />
<Route path="/api/v1/app/viewreports" element={<ReportCard />} />
</Routes>
</PageLayout>
</Router>

React Router Navigate Issue in Semantic Ui React

I have an issue with navigating pages via Route.
I used semantic ui react components to handle with the issue.
When I link any item in navbar, the url is changed like http://localhost:3000/ to http://localhost:3000/list but the relevant component page cannot open.
How can I fix it?
Here is my index.js code shown below.
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter> ,
document.getElementById('root')
);
Here is my App.js code shown below.
function App() {
return (
<div className="App">
<Container style={{"marginTop": "20px"}}>
<Header />
<Route path="/">
<AccordionComponent items={items} />
</Route>
<Route path="/list">
<Search />
</Route>
<Route path="/dropdown">
<DropdownForm options={options}/>;
</Route>
<Route path="/translate">
<Translate />
</Route>
</Container>
</div>
);
}
export default App;
Here is my Route Component shown below.
const Route = ({ path, children }) => {
return window.location.pathname === path ? children : null;
};
export default Route;
Here is my Header Component shown below.
import React, { useState } from 'react';
import { Menu } from 'semantic-ui-react'
import { Link } from "react-router-dom";
const Header = () => {
const [activeItem, setActiveItem] = useState('Accordion');
const handleItemClick = (name) => setActiveItem(name)
return (
<Menu secondary pointing>
<Menu.Item
as={Link} to="/"
name='Accordion'
active={activeItem === 'Accordion'}
onClick={() => handleItemClick('Accordion')}
/>
<Menu.Item
as={Link} to="/list"
name='Search'
active={activeItem === 'Search'}
onClick={() => handleItemClick('Search')}
/>
<Menu.Item
as={Link} to="/dropdown"
name='Dropdown'
active={activeItem === 'Dropdown'}
onClick={() => handleItemClick('Dropdown')}
/>
<Menu.Item
as={Link} to="/translate"
name='Translate'
active={activeItem === 'Translate'}
onClick={() => handleItemClick('Translate')}
/>
</Menu>
);
};
export default Header;
Wrap de routes with Switch as this example:
function App() {
return (
<div className="App">
<Container style={{"marginTop": "20px"}}>
<Header />
<Switch>
<Route path="/">
<AccordionComponent items={items} />
</Route>
<Route path="/list">
<Search />
</Route>
<Route path="/dropdown">
<DropdownForm options={options}/>;
</Route>
<Route path="/translate">
<Translate />
</Route>
</Switch>
</Container>
</div>
);
}
export default App;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
Docs: https://reactrouter.com/web/api/Switch

Reactjs - props not changing during Routing

I have a BrowserRouter which renders different components based on the Route. Most, of these components have similar markup.
So, I created a Wrapper component which will recieve props, and render its {children} if provided. This Wrapper is called in Route's.
import React, {Component} from 'react'
import Context from '../../provider'
import {
BrowserRouter,
Route,
Redirect,
Switch,
} from "react-router-dom"
import {
Container,
Row,
Col,
} from 'reactstrap'
import Profile from './ContentComponent/Profile'
import Subreddit from './ContentComponent/Subreddit'
import PostExpanded from './ContentComponent/PostExpanded'
import InfoComponent from './InfoComponent'
import SwitchTab from './ContentComponent/Subreddit/SwitchTab'
import NewPost from './ContentComponent/assets/NewPost'
import './style.css'
class Wrapper extends React.Component {
componentDidMount() {
this.props.setActiveTab(this.props.activeTab);
}
render() {
{console.log('Wrapper props: ', this.props)}
return (
<Row>
<Col md='8' id='content-block'>
<SwitchTab />
{this.props.children}
</Col>
<Col md='4' id='info-block'>
<InfoComponent info={this.props.info} {...this.props}/>
</Col>
</Row>
)
}
}
export default class BodyComponent extends Component {
render() {
return (
<BrowserRouter>
<Context.Consumer>
{context => {
return (
<Container>
<Switch>
<Route
exact
path='/'
render={() =>
<Redirect to='r/home/' />
}
/>
<Route
exact
path='/r/home/'
render={() =>
<Wrapper
setActiveTab={context.toggleTab}
activeTab={'1'}
info='home'
/>
}
/>
<Route
exact
path='/r/popular/'
render={() =>
<Wrapper
setActiveTab={context.toggleTab}
activeTab={'2'}
info='popular'
/>
}
/>
<Route
exact
path='/r/all/'
render={() =>
<Wrapper
setActiveTab={context.toggleTab}
activeTab={'3'}
info='all'
/>
}
/>
<Route
exact
path='/u/:username/'
render={(props) => {
return (
<Wrapper
setActiveTab={context.toggleTab}
activeTab={'4'}
info='user'
user={props.match.params.username}
>
<Profile username={props.match.params.username} />
</Wrapper>
)
}}
/>
<Route
exact
path = '/r/:subreddit/new/'
render={(props) => {
return (
<Wrapper
setActiveTab={context.toggleTab}
activeTab={'4'}
info='subreddit'
subreddit={props.match.params.subreddit}
>
<NewPost />
</Wrapper>
)
}}
/>
<Route
exact
path = '/r/:subreddit/post/:postid/'
render={(props) => {
return (
<Wrapper
setActiveTab={context.toggleTab}
activeTab={'4'}
info='subreddit'
subreddit={props.match.params.subreddit}
>
<PostExpanded
subreddit={props.match.params.subreddit}
postid={props.match.params.postid}
/>
</Wrapper>
)
}}
/>
<Route
exact
path='/r/:subreddit/'
render={(props) => {
return (
<Wrapper
setActiveTab={context.toggleTab}
activeTab={'4'}
info='subreddit'
subreddit={props.match.params.subreddit}
>
<Subreddit subreddit={props.match.params.subreddit} />
</Wrapper>
)
}}
/>
<Route
exact
path = '/new/'
render={(props) => {
return (
<Wrapper
setActiveTab={context.toggleTab}
activeTab={'4'}
info='new'
>
<NewPost />
</Wrapper>
)
}}
/>
</Switch>
</Container>
)
}}
</Context.Consumer>
</BrowserRouter>
)
}
}
I am facing multiple problems here and I think they can all be fixed at once, I don't know how?
The Wrapper props are not getting changed when I am changing the URL
using props.history.push:
<NavItem>
<NavLink
className={classnames({ active: context.activeTab === '1' })}
onClick={() =>{
context.toggleTab('1');
this.props.history.push('/r/home/')
}}
>
Home
</NavLink>
</NavItem>
<NavItem>
<NavLink
className={classnames({ active: context.activeTab === '2' })}
onClick={() => {
context.toggleTab('2');
this.props.history.push('/r/popular/')
}}
>
Popular
</NavLink>
</NavItem>
I think I got the problem while going through my code. So, the problem started when I wanted to use props.history.push in my HeaderComponent. I was getting error so I wrapped it with BrowserRouter and exported withRouter() which enabled me to use props.history.push
So, unknowingly I have created 2 BrowserRouter's:
<React.Fragment>
<BrowserRouter>
<NavbarComponent />
<TabComponent />
</BrowserRouter>
<BrowserRouter>
<Switch>
<Route ... />
<Route ... />
</Switch>
</BroserRouter>
</React.Fragment>
So, I was changing URLs in TabComponent and expecting that to change my Route's and modify content.
Having a global BrowserRouter (don't think that global's the right word but) solved the problem.
<React.Fragment>
<BrowserRouter>
<NavbarComponent />
<TabComponent />
<Switch>
<Route ... />
<Route ... />
</Switch>
</BroserRouter>
</React.Fragment>

Categories