React URL Link changes but not rendering - reactjs

I'm using Link in my <nav> which does change the URL but isn't switching the page component!
Question: Why isn't my page components loading with the URL changes?
File: index.tsx
import { render } from 'react-dom';
import { Provider } from 'react-redux';
import { store } from '#store';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import * as serviceWorker from './serviceWorker';
import {
SigninPage,
HomePage,
UserManagementPage,
SiteContentPage,
} from '#pages';
import { ProtectedRoute } from '#components';
import '#styles/main.scss';
import './index.scss';
export function App() {
return (
<Provider store={store}>
<div id='app'>
<Router>
<Switch>
<Route exact path='/signin' component={SigninPage} />
<ProtectedRoute path='/' component={HomePage} />
<ProtectedRoute path='/sitecontent' component={SiteContentPage} />
<ProtectedRoute
path='/usermanagement'
component={UserManagementPage}
/>
</Switch>
</Router>
</div>
</Provider>
);
}
render(<App />, document.getElementById('root'));
serviceWorker.unregister();
File: ProtectedRoute.tsx
import React from 'react';
import { Route, Redirect } from 'react-router-dom';
import { useSelector } from 'react-redux';
import { IAppState } from '#store';
import { ReactComponent as AdaptLogo } from '#assets/images/adaptLogo.svg';
import { NavLink, Link } from 'react-router-dom';
interface IProtectedRoute {
path: string;
component: React.FunctionComponent;
}
export const ProtectedRoute: React.FC<IProtectedRoute> = ({
path,
component: Component,
}) => {
// check if user is authenticated or else route them to the SigninPage
const isUserAuthenticated = useSelector(
(state: IAppState) => state.user.authenticated
);
return (
<>
{isUserAuthenticated ? (
<>
<header>
<AdaptLogo id='adapt-logo' />
</header>
<nav>
<Link to='/'>Home Page</Link>
<Link to='/usermanagement'>User Management Page</Link>
<Link to='/sitecontent'>Site Content Page</Link>
</nav>
<main>
<Route exact path={path} render={(props) => <Component />} />
</main>
</>
) : (
<Redirect to='/signin' />
)}
</>
);
};

Related

React fullpageJS and react-router-dom

I am trying to use react fullpageJS and react router dom to create a carousel but it shows empty screen, Here's the code I am using:
APP.JS:
import { Route, Routes } from "react-router-dom";
import Navigation from "./routes/navigation/navigation.component";
import Home from "./components/home/home.component";
function App() {
const About = () => {
return (
<div>
<h1>This is about</h1>
</div>
);
};
return (
<div>
<Routes>
<Route path="/" element={<Navigation />}>
<Route index element={<Home />} />
<Route path="/about" element={<About />} />
</Route>
</Routes>
</div>
);
}
export default App;
Home.jsx:
import { useState, useEffect, React } from "react";
import ProjectPreview from "../project-preview/project-preview.component";
import ReactFullpage from "#fullpage/react-fullpage";
// import "fullpage.js/vendors/scrolloverflow";
import PROJECTS_DATA from "../../Projects";
const Home = () => {
const [projectsToPreview, setProjects] = useState([]);
useEffect(() => {
setProjects(PROJECTS_DATA);
}, []);
<ReactFullpage
render={() => {
return (
<ReactFullpage.Wrapper>
<ReactFullpage.Wrapper>
{projectsToPreview.map((project) => {
return (
<div className="section" key={project.id}>
<h1>Test</h1>
<ProjectPreview project={project} />
</div>
);
})}
</ReactFullpage.Wrapper>
</ReactFullpage.Wrapper>
);
}}
/>;
};
export default Home;
The rendered screen shows only the navbar component but the content in the slider appear neither on the screen nor in the javascript dom
index.js:
import React from "react";
import ReactDOM from "react-dom/client";
import { BrowserRouter } from "react-router-dom";
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<React.StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>
);
reportWebVitals();
Navigation.jsx
import { Link, Outlet } from "react-router-dom";
import { Nav, Navbar } from "react-bootstrap";
const Navigation = () => {
return (
<>
<Navbar expand="lg" variant="dark">
<Link className="navbar-brand" to="/">
LOGO
</Link>
<Nav className="ms-auto">
<Link className="nav-link" to="/about">
About
</Link>
</Nav>
</Navbar>
<Outlet />
</>
);
};
export default Navigation;
I suspect the issue is that the Navigation component isn't rendering an Outlet component for the nested routes to render their element into.
Navigation should render an Outlet.
Example:
import { Outlet } from 'react-router-dom';
const Navigation = () => {
...
return (
... nav and layout UI
<Outlet /> // <-- nested routes render content here
...
);
};

`No routes matched location "/" ` warning shown on the console

I am trying to implement a small project and got an error/warning like above title.
Here is my Index.jsx:
import React, { Suspense } from "react";
import ReactDOM from "react-dom";
import { Provider } from "react-redux";
import { BrowserRouter} from "react-router-dom";
import { App } from "./components/app";
ReactDOM.render(
<React.StrictMode>
<Provider store={store}>
<Suspense fallback={<div>Loading...</div>}>
<BrowserRouter>
<App />
</BrowserRouter>
</Suspense>
</Provider>
</React.StrictMode>,
document.getElementById("root")
);
App.jsx:
import React, { useEffect } from "react";
import { makeStyles } from "#material-ui/core/styles";
import { Container } from "#material-ui/core";
import { ToastContainer } from "react-toastify";
import { Route, Routes } from "react-router-dom";
import { useSelector, useDispatch } from "react-redux";
import Sidebar from "../sidebar/Sidebar";
import TopNav from "../topnav/TopNav";
import { AppRoutes } from "../AppRoutes";
import ThemeAction from "../../store/actions/ThemeAction";
import "./App.scss";
const useStyles = makeStyles({
contentStyle: {
margin: "30px auto",
},
});
export const App = () => {
const themeReducer = useSelector((state) => state.ThemeReducer);
const classes = useStyles();
const dispatch = useDispatch();
useEffect(() => {
const themeClass = localStorage.getItem("themeMode", "theme-mode-light");
const colorClass = localStorage.getItem("colorMode", "theme-mode-light");
dispatch(ThemeAction.setMode(themeClass));
dispatch(ThemeAction.setColor(colorClass));
}, [dispatch]);
return (
<Routes>
<Route
render={(routeProps) => (
<div className={`app ${themeReducer.mode} ${themeReducer.color}`}>
<Sidebar routeProps={routeProps} />
<div className="app__content">
<TopNav />
<div className="app__content-main">
<ToastContainer />
<Container className={classes.contentStyle} maxWidth="sm">
<AppRoutes />
</Container>
</div>
</div>
</div>
)}
/>
</Routes>
);
};
And AppRoutes.jsx:
import React from "react";
import { Route, Routes } from "react-router-dom";
import Customers from "../pages/Customers";
import { Dashboard } from "../pages/Dashboard";
import { UserLogin } from "./User/Login";
import { UserSignup } from "./User/Signup/UserSignup";
export const AppRoutes = () => {
return (
<Routes>
<Route index path="/" element={<Dashboard />} />
<Route path="customers" component={<Customers />} />
<Route path="userLogin" element={<UserLogin />} />
<Route path="userSignup" element={<UserSignup />} />
</Routes>
);
};
And the project is not running) I mean white blank on browser window while there is no error except index.tsx:25 No routes matched location "/" .
In react-router-dom#6 there are no longer any render (or component or children function props). Remove the Routes and Route component in App. You will also update Sidebar to access the location object via hook.
App
return (
<div className={`app ${themeReducer.mode} ${themeReducer.color}`}>
<Sidebar routeProps={routeProps} />
<div className="app__content">
<TopNav />
<div className="app__content-main">
<ToastContainer />
<Container className={classes.contentStyle} maxWidth="sm">
<AppRoutes />
</Container>
</div>
</div>
</div>
);
Sidebar
const Sidebar = () => {
const location = useLocation();
const activeItem = sidebar_items.findIndex(
(item) => item.route === location.pathname
);
return (
<div className="sidebar">
<div className="sidebar__logo">
<img src={logo} alt="company logo" />
</div>
{sidebar_items.map((item, index) => (
<Link to={item.route} key={index}>
<SidebarItem
title={item.display_name}
icon={item.icon}
active={index === activeItem}
/>
</Link>
))}
</div>
);
};
AppRoutes
Remove the index prop from the "/" route. When you specify an index route the path prop is ignored. Also, make sure all the routes are correctly using the element prop.
<Routes>
<Route path="/" element={<Dashboard />} />
<Route path="customers" element={<Customers />} />
<Route path="userLogin" element={<UserLogin />} />
<Route path="userSignup" element={<UserSignup />} />
</Routes>

functional component disappears while using react-router-dom

I just wanted to make a simple project setup with react-router-dom but whenever I'm using route the entire page becomes blank. my Nav disappears. why ?
there was a similar question for class component so it wasn't helpful for me.
App.js :
import "./App.css";
import Nav from "./components/Nav";
import Products from "./components/Products";
import About from "./components/About";
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
function App() {
return (
<>
<Router>
<Nav />
<Route path="/about" component={About} />
<Route path="/products" component={Products} />
<About />
</Router>
</>
);
}
export default App;
Nav:
import React from "react";
import Navstyle from "../styles/Nav.module.css";
const Nav = () => {
return (
<nav className={Navstyle.Nav}>
<ul className={Navstyle.nav_links}>
<li>
Home
</li>
<li>
Products
</li>
<li>
About
</li>
</ul>
</nav>
);
};
export default Nav;
other components are just returning h2 tags
You need to use a layout (as a HOC) to add a navbar or other things to your code.
just use the components with routes in your router.
I recommend defining the Layout in another file.
export default function App() {
return (
<Layout>
<Router>
<Route component={Products} path="/products" exact />
<Route component={About} path="/about" exact />
</Router>
</Layout>
);
}
const Products = () => {
return <p>Products</p>;
};
const About = () => {
return <p>about</p>;
};
const Navbar = () => {
return <p>navbar</p>;
};
const Layout = ({ children }) => {
return (
<div>
<Navbar />
<div>{children}</div>
</div>
);
};
I find out ! the problem was YouTube videos I guess. first of all you must add BrowserRouter to your index.js not app.js , like this :
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
import { BrowserRouter } from "react-router-dom";
ReactDOM.render(
<React.StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>,
document.getElementById("root")
);
reportWebVitals();
after that you must use react router in that way , not the way I tried first :
import "./App.css";
import Nav from "./components/Nav";
import Products from "./components/Products";
import About from "./components/About";
import { Route, Routes } from "react-router-dom";
function App() {
return (
<>
<Nav />
<Routes>
<Route path="/About" element={<About />} />
</Routes>
</>
);
}
export default App;
during the changes of react-router-dom in version 6 , this is the new way of using router.
the link of docs :
https://reactrouter.com/docs/en/v6/getting-started/overview

history push with switch doesn't redirect

I'm new to react.
I've used CRA to create my app.
I try to build a smooth full page transition, not only on the component who's rendered as we can do with react-transition-group
To do so, I try to manually redirect when I click on a tag.
But only the url is changed but the page is not re-rendered...
I've tried with this.context (undefined), < Redirect >, I red the docs and many articles but couldn't figure out how it can work.
Here is my code
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import * as serviceWorker from './serviceWorker';
import { BrowserRouter } from 'react-router-dom';
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>,
document.getElementById('root')
);
serviceWorker.register();
App.js
import React, { Component } from 'react'
import { BrowserRouter as Router, Switch, Route, withRouter } from 'react-router-dom';
import './App.scss';
import history from 'js/core/history.js'
class App extends Component {
constructor(props) {
super(props);
this.state = {
isRedirecting: false
}
this.isRedirecting = false;
this.taContainer = React.createRef();
}
redirectHandler(location) {
if(location != null && location != undefined && !this.state.isRedirecting) {
this.setState({isRedirecting: true})
setTimeout(() => {
history.push(location);
this.setState({isRedirecting: false})
}, 1000)
}
}
render() {
return (
<div className="app">
<div className="inner-app">
<BackScene></BackScene>
<Router>
<Switch>
<Route exact path='/' render={(props) => <Home {...props} onClick={this.redirectHandler.bind(this)} />} />
<Route exact path={'/experiments'} render={(props) => <Experiments {...props} onClick={this.redirectHandler.bind(this)}/>
<Route exact path={'/experiments/:cat'} render={(props) => <Experiments {...props} />} />
<Route exact path={'/experiments/:cat/:slug'} render={(props) => <SingleProject {...props} />} />
<Route exact path={'/shader'} render={(props) => <ShaderTemplatePage {...props} />} />
</Switch>
</Router>
<div className="ta" ref={this.taContainer}>
<div className="ta-first"></div>
<div className="ta-second"></div>
</div>
</div>
</div>
);
}
}
export default withRouter(App);
Home.js
import React, { Component } from 'react'
export default class Home extends Component {
render() {
return (
<div className='home page'>
<div className="inner-home">
<div className="content">
<h1 className='title'>Title</h1>
<a className='button' onClick={() => {this.props.onClick('/experiments')}}>Get started !<span></span></a>
<ul className="socials">
<li><i className='icon icon-twitter'></i></li>
<li><i className='icon icon-instagram'></i></li>
</ul>
</div>
</div>
</div>
)
}
}
history.js
import { createBrowserHistory } from "history";
export default createBrowserHistory();
Can you try passing history object as props to the <BrowserRouter> component in the index.jsx file?
import history from 'js/core/history.js'
<BrowserRouter history={history}>
<App />
</BrowserRouter>

Should not use <Link> outside a <Router> Error

I am trying to navigate through different screens with BottomNavigationAction from material ui and i get this error You should not use <Link> outside a <Router>
Tab.js:
import React from 'react';
import { Link } from 'react-router-dom';
import { withStyles } from '#material-ui/core/styles';
import BottomNavigation from '#material-ui/core/BottomNavigation';
import BottomNavigationAction from '#material-ui/core/BottomNavigationAction';
// icons
import HomeIcon from '#material-ui/icons/Home';
import DashboardIcon from '#material-ui/icons/Dashboard';
import PaymentIcon from '#material-ui/icons/Payment';
import FaceIcon from '#material-ui/icons/Face';
import AtmIcon from '#material-ui/icons/Atm';
const styles = {
root: {
position: 'absolute',
bottom: 0,
width: '100%',
cursor: 'pointer'
},
wrapper: {
minWidth: '0px'
}
};
class Tab extends React.Component {
state = { value: 0 };
handleChange = (event, value) => {
this.setState({ value });
};
render() {
const { classes } = this.props;
const { value } = this.state;
return (
<div>
<BottomNavigation value={value} onChange={this.handleChange} className={classes.root}>
<Link to="/">
<BottomNavigationAction label="Home" value="home" icon={<HomeIcon />} className={classes.wrapper}/>
</Link>
</BottomNavigation>
</div>
);
}
}
export default withStyles(styles)(Tab);
app.js is where i am trying to render the Tab.js so it stays on all the pages! and my routes are also rendered there
App.js
import React, { Component } from 'react';
import {BrowserRouter} from 'react-router-dom';
import Routers from './Routers';
import Tab from './components/Tab';
class App extends Component {
render() {
return (
<div>
<Tab />
<Routers />
</div>
);
}
}
export default App;
routes.js is where i identify routes:
Routes.js
import React from 'react';
import { BrowserRouter, Route, Switch, Redirect } from 'react-router-dom';
import { createStore, applyMiddleware } from 'redux';
import promise from 'redux-promise';
import { Provider } from 'react-redux';
import Home from './components/Home';
import Profile from './components/Profile';
import Login from './components/auth/Login';
import reducers from './reducers';
import configureStore from './store/configueStore';
import {getAuthToken} from './actions/auth';
const store = configureStore();
const Routers = () => (
<Provider store={store}>
<BrowserRouter>
<div>
<Switch>
<Route path='/' component={Home} exact={true}/>
<Route path='/login' component={Login} exact={true}/>
<Route path='/register' component={Login} exact={true}/>
<Route path='/profile' component={Profile} exact={true}/>
</Switch>
</div>
</BrowserRouter>
</Provider>
);
export default Routers;
how to i use link in my Tab.js file and make the redirection happen
and i will love an explanation on why this problem is accruing and how will i be able to fix it with my current file structure.
And is my file structure good? as i am having a different file for my routes and rendering it inside my app.js
Your Link and Routes must all have a Router provider higher up in the tree. Also you must use a single BrowserRouter. You can change your configuration to the following
const Routers = () => (
<div>
<Switch>
<Route path='/' component={Home} exact={true}/>
<Route path='/login' component={Login} exact={true}/>
<Route path='/register' component={Login} exact={true}/>
<Route path='/profile' component={Profile} exact={true}/>
</Switch>
</div>
);
class App extends Component {
render() {
return (
<div>
<Provider store={store}>
<BrowserRouter>
<div>
<Tab />
<Routers />
</div>
</BrowserRouter>
</Provider>
</div>
);
}
}
You don't have <BrowserRouter> parent for the link used in your tab.js file. Make following changes to your App.js file to make your code work:
import React, { Component } from 'react';
import { BrowserRouter } from 'react-router-dom';
import Routers from './Routers';
import Tab from './components/Tab';
class App extends Component {
render() {
return (
<BrowserRouter>
<div>
<Tab />
<Routers />
</div>
</BrowserRouter />
);
}
}
export default App;
I think you should wrap in .
For details you can also refer to Key Concepts For React-Router and React-Router With Material-UI

Resources