The functions onEnter and onUpdate, does not work on react 4. I try different way to listen to this change but I start to turn in circles.
I would like to manage everything in my App component.
This function would allow me to close my Menu at each change of course. (isOpen) ==> False
Git of this project: https://github.com/marcdubois71450/Library-Exercise
I use react-router-dom, and react 4
import React, {Component} from 'react';
import { BrowserRouter, Route } from 'react-router-dom';
import PropTypes from 'prop-types';
import { scaleDown as Menu } from 'react-burger-menu'
import './App.css';
import Navigation from '../Navigation';
import LandingPage from '../Landing';
import SignUpPage from '../SignUp';
import SignInPage from '../SignIn';
import PasswordForgetPage from '../PasswordForget';
import HomePage from '../Home';
import AccountPage from '../Account';
import AdminPage from '../Admin';
import * as ROUTES from '../../constants/routes';
export default class App extends Component {
render() {
return (
<Router>
<div>
<Menu pageWrapId={ "page-wrap" } outerContainerId={ "outer-container" } isOpen={this.isOpen} >
<Navigation />
</Menu>
<main id="page-wrap">
<Route exact path={ROUTES.LANDING} component={LandingPage} />
<Route path={ROUTES.SIGN_UP} onEnter={this.onChangeRoute} component={SignUpPage} />
<Route path={ROUTES.SIGN_IN} onEnter={this.onChangeRoute} component={SignInPage} />
<Route path={ROUTES.PASSWORD_FORGET} onEnter={this.onChangeRoute} component={PasswordForgetPage} />
<Route path={ROUTES.HOME} onEnter={this.onChangeRoute} component={HomePage} />
<Route path={ROUTES.ACCOUNT} onEnter={this.onChangeRoute} component={AccountPage} />
<Route path={ROUTES.ADMIN} onEnter={this.onChangeRoute} component={AdminPage} />
</main>
</div>
</Router>
);
}
}
I would like to manage everything in my App component.
Use render instead of onEnter in React Router V4
Exemple from the doc:
// convenient inline rendering
<Route path="/home" render={() => <div>Home</div>}/>
// wrapping/composing
const FadingRoute = ({ component: Component, ...rest }) => (
<Route {...rest} render={props => (
<FadeIn>
<Component {...props}/>
</FadeIn>
)}/>
)
<FadingRoute path="/cool" component={Something}/>
Render Function
Related
I have coded a landing page in react, and in a separate project a react/typescript app. How would I go about setting my website up so that when there's no user auth, the landing page and all its features show, and when logged in change the landing page to the actual app [e.g. twitter]. I realise that in my app project folder, I will need to change a few things, but I'm not sure what exactly.
React landing page app.jsx:
import React, { useEffect, useState } from 'react';
import {
Routes,
Route,
useLocation
} from 'react-router-dom';
import 'aos/dist/aos.css';
import './css/style.css';
import AOS from 'aos';
import Home from './pages/Home';
import SignIn from './pages/SignIn';
import SignUp from './pages/SignUp';
import ResetPassword from './pages/ResetPassword';
import LearnMore from './pages/LearnMore';
import AboutUs from './pages/AboutUs';
import ComingSoon from './pages/ComingSoon';
import RecosiaPay from './pages/RecosiaPay';
import RecosiaBank from './pages/RecosiaBank';
import Guides from './pages/Guides';
import PrivacyPolicy from './pages/PrivacyPolicy';
import Support from './pages/Support';
import Pitchdeck from './pages/PitchDeck';
function App() {
const location = useLocation();
useEffect(() => {
AOS.init({
once: true,
disable: 'phone',
duration: 700,
easing: 'ease-out-cubic',
});
});
useEffect(() => {
document.querySelector('html').style.scrollBehavior = 'auto'
window.scroll({ top: 0 })
document.querySelector('html').style.scrollBehavior = ''
}, [location.pathname]); // triggered on route change
return (
<>
<Routes>
<Route exact path="/" element={<Home />} />
<Route path="/signin" element={<SignIn />} />
<Route path="/signup" element={<SignUp />} />
<Route path="/guides" element={<Guides />} />
<Route path="/support" element={<Support />} />
<Route path="/pitch-deck" element={<Pitchdeck />} />
<Route path="/privacy-policy" element={<PrivacyPolicy />} />
<Route path="/recosia-pay" element={<RecosiaPay />} />
<Route path="/recosia-bank" element={<RecosiaBank />} />
<Route path="/learn-more" element={<LearnMore />} />
<Route path="/coming-soon" element={<ComingSoon />} />
<Route path="/about-us" element={<AboutUs />} />
<Route path="/reset-password" element={<ResetPassword />} />
</Routes>
</>
);
}
export default App;
and React Typescript [actual application] App.jsx code:
import type { AppProps } from 'next/app'
import { ChakraProvider } from '#chakra-ui/react'
import { theme } from '../chakra/theme';
import Layout from "../components/Layout/Layout";
import { RecoilRoot } from 'recoil';
function MyApp({ Component, pageProps }: AppProps) {
return (
<RecoilRoot>
<ChakraProvider theme={theme}>
<Layout>
<Component {...pageProps} />
</Layout>
</ChakraProvider>
</RecoilRoot>
);
}
export default MyApp;
I would set up some form of a state manager using redux, or just the context api from react. Once you have this, you can separate your routes into an <AuthenticatedApp/> and an <UnauthenticatedApp/>. Based on the authentication status put on state, you can have a memoized value listening for changes to that authentication status. When changed, you can switch between which set of routes are displayed to the user!
You can either use an authentication library like auth-0, or
You can use a state manager (useState, useContext, redux, etc.) to track whether the user has logged in or not, and show the route that you want.
This is a good pattern to start with:
https://blog.logrocket.com/complete-guide-authentication-with-react-router-v6/
I want authenticated routes if user is not logged in the page should not be accessible like if someone enters in the url localhost.../admin/dashboard he should not be able to navigate instead he should be taken to signin page if not logged in.
I'm using react-router v6 and creating private routes for my application.
AdminRoute.js File Code is below
import React from "react";
import { Route, Navigate} from 'react-router-dom';
import { isAuthenticated } from "../helper/auth";
//props component is assigned to Component
//...rest spreading props property but reassigning it to a variable called rest
const AdminRoute = ({ component: Component, ...rest }) => {
return (
<Route
{...rest}
render={(props) =>
isAuthenticated() && isAuthenticated().role === 1 ? (
<Component {...props} />
) : (
<Navigate to = '/signin' />
)
}
/>
)
};
export default AdminRoute;
App.js File Code is below
import React from 'react';
import {BrowserRouter, Route, Routes} from 'react-router-dom';
import Header from './Header';
import Home from './Home';
import Signup from './Signup';
import Signin from './Signin';
import ForgotPassword from './forgot-password';
import UserDashboard from './UserDashboard';
import AdminDashboard from './AdminDashboard';
import ShowroomDashboard from './ShowroomDashboard';
import AdminRoute from './AdminRoute';
import NotFound from './NotFound';
const App = () => (<BrowserRouter>
<Header />
<main>
<Routes>
<Route exact path='/' element={<Home />} />
<Route exact path='/signup' element={<Signup />} />
<Route exact path='/signin' element={<Signin />} />
<Route exact path='/forgotpassword' element={<ForgotPassword />} />
<Route exact path='/user/dashboard' element={<UserDashboard />} />
<AdminRoute exact path='/admin/dashboard' element={<AdminDashboard />} />
<Route exact path='/showroom/dashboard' element={<ShowroomDashboard />} />
<Route exact path = '*' element={<NotFound />} />
</Routes>
</main>
</BrowserRouter>
);
export default App;
react-router-dom no longer supports custom route components, preferring now component wrappers that handle the auth logic and render either the children prop or an Outlet for nested routes, or the redirect.
Wrap a single "Route" component:
import React from "react";
import { Navigate } from 'react-router-dom';
import { isAuthenticated } from "../helper/auth";
const AdminRoute = ({ children }) => {
return isAuthenticated()?.role === 1
? children
: <Navigate to='/signin' replace />;
};
...
<Route
path='/admin/dashboard'
element={(
<AuthRoute>
<AdminDashboard />
</AuthRoute>
)}
/>
Wrap nested Route components:
import React from "react";
import { Navigate, Outlet } from 'react-router-dom';
import { isAuthenticated } from "../helper/auth";
const AdminWrapper = () => {
return isAuthenticated()?.role === 1
? <Outlet />
: <Navigate to='/signin' replace />;
};
...
<Route path='/admin/dashboard/*' element={<AdminWrapper />}>
<Route index element={<AdminDashboard />} />
... any other '/admin/dashboard/*' routes ...
</Route>
This question already has answers here:
React Router works only after refreshing the page
(5 answers)
Closed 1 year ago.
I'm new to react & react router dom v5, also my english is bad. Thank you in advance for helping me.
my problem:
I have 2 Main Routes in my App.js route
import { Suspense } from 'react';
import {BrowserRouter as Router, Switch, Route} from 'react-router-dom'
/* Pges */
import AdminContainer from './Pages/Admin/AdminContainer';
import PublicContainer from './Pages/Public/PublicContainer';
import NotFound from './Pages/NotFound'
import AuthContainer from './Pages/Auth/AuthContainer';
/* Protected Route */
/* Helpers */
function App() {
console.log("APP")
return (
<Suspense fallback={(<p>Loading</p>)}>
<Router>
<Switch>
<Route path="/auth" component={AuthContainer} />
<Route path="/admin" component={AdminContainer} />
<Route path="/*" component={PublicContainer} />
<Route path="*" component={NotFound} />
</Switch>
</Router>
</Suspense>
)
}
export default App;
the authcontainer have 2 sub routes
"/signin"
"/signup"
import React from "react";
import {
BrowserRouter as Router,
Switch,
Route,
withRouter
} from "react-router-dom";
// PAGES
import Signin from "../Auth/Signin";
import Signup from "../Auth/Signup";
const AuthContainer = () => {
console.log("AUTH")
return (
<div>
<Router>
<Switch>
<Route exact path="/auth" component={Signin}/>
<Route exact path="/auth/signin" component={Signin}/>
<Route exact path="/auth/signup" component={Signup}/>
</Switch>
</Router>
</div>
);
};
export default withRouter(AuthContainer);
then the my publiccontainer have 3 sub routes
"/"
"/product"
"/mycart"
/* Dependencies */
import { Route, Switch, BrowserRouter as Router } from 'react-router-dom'
/* Components */
import Header from "../../Components/Header"
import Products from "./Products"
import Home from "./Home"
import UserProfile from "../User/AccountProfile"
import MyCart from '../Public/MyCart'
const PublicContainer = () => {
console.log("PUBLIC")
return (
<div>
<Router>
<Header />
<Switch>
<Route exact path='/' render={(props) => <Home />} />
<Route exact path='/products' render={(props) => <Products />} />
<Route exact path='/mycart' render={(props) => <MyCart isAuth={false} />} />
</Switch>
</Router>
</div>
)
}
export default PublicContainer
the my cart component will only render if isAuth is true, else it will redirect to "/auth/signin"
import React from 'react'
import { Redirect } from 'react-router'
const MyCart = ({isAuth}) => {
if(!isAuth)
return (<Redirect from='*' to='/auth/signin'></Redirect>)
return (
<div>
my cart
</div>
)
}
export default MyCart
The problem is, its trying to redirect to "/auth/signin" but it is still in the "/" page
When i hit reload it finally redirect to "/auth/signin"
How can i fix this issue, I really appreciate your help
UPDATE
this is overview of my planned routes
By the way i think when the mycart isAuth is false then it tries to Link to /auth/signin which causes the link in the top url to correctly point to auth signin, but after that it only checks the subroutes of the publiccontainer instead of checking the app.js routes
But when i reload it, it start searching the correct route from the app.js routes which return the expected route & page which is the sign in
I read a almost similar question in terms of only rendering the correct path when hitting refresh/reload
here React Router works only after refreshing the page
The problem was i'm wrapping the sub routes with a new router, so i tried removing the Router jsx that is wrapping the Switch> & other subroutes in both AuthContainer.js & PublicContainer.js
this is the updated AuthContainer.js
import React from "react";
import {
BrowserRouter as Router,
Switch,
Route,
withRouter
} from "react-router-dom";
// PAGES
import Signin from "../Auth/Signin";
import Signup from "../Auth/Signup";
const AuthContainer = () => {
console.log("AUTH")
return (
<div>
<Switch>
<Route exact path="/auth/signin" component={Signin}/>
<Route exact path="/auth/signup" component={Signup}/>
<Route exact path="/auth" component={Signin}/>
</Switch>
</div>
);
};
export default withRouter(AuthContainer);
And this is the PublicContainer.js
/* Dependencies */
import { Route, Switch } from 'react-router-dom'
/* Components */
import Header from "../../Components/Header"
import Products from "./Products"
import Home from "./Home"
import UserProfile from "../User/AccountProfile"
import MyCart from '../Public/MyCart'
/* Protected */
const PublicContainer = ({toAuth}) => {
console.log("PUBLIC")
return (
<div>
<Header />
<Switch>
<Route exact path='/products' render={(props) => <Products />} />
<Route exact path='/profile' render={(props) => <UserProfile />} />
<Route exact path='/mycart' render={(props) => <MyCart />} />
<Route exact path='/' render={(props) => <Home />} />
</Switch>
</div>
)
}
export default PublicContainer
I am building an E-Commerce MERN Stack Web Application. The loading time of my Home Page as tested by Lighthouse is more than 12s.
I have hence posted the App.js file and my main main homepage.js file.
How can I implement code splitting on my homepage.js file (using Lazy-Suspense method o any other)?
homepage.js
import React, { Component } from 'react';
import Header from '../header/header';
import About from '../about/about';
import Services from '../services/services';
import Footer from '../footer/footer';
import Navbar from '../navbar/navbar';
export default class Homepage extends Component {
state = {
response: '',
email: '****.com',
password:'****',
message:'',
};
render() {
let loggedIn = this.props.loggedIn;
console.log(loggedIn)
return (
<div className="App">
<Navbar />
<Header resumeData={{name:this.state.email,}}/>
<Services resumeData={{name:this.state.email,}}/>
<About resumeData={{name:this.state.email,}}/>
<Footer resumeData={{name:this.state.email,}}/>
</div>
);
}
}
App.js
import React, { Component } from 'react';
import { BrowserRouter, Route, Switch } from 'react-router-dom';
import Homepage from './components/homepage/homepage';
import LogIn from './components/login/login';
import SignUp from './components/signup/signup';
import Reset from './components/reset/reset';
import Account from './components/account/account';
import Verify from './components/verify/verify';
import Shop from './components/shop/shop';
import Cart from './components/cart/cart';
import Checkout from './components/cart/checkout';
import Admin from './components/admin/admin';
import Order from './components/order/order';
import Subscription from './components/order/subscription';
import Subscribe from './components/subscribe/subscribe';
class App extends Component {
render() {
return (
<BrowserRouter>
<Switch>
<Route path="/" component={Homepage} exact/>
<Route path="/shop" component={Shop} />
<Route path="/cart" component={Cart} />
<Route path="/checkout:what" component={Checkout} />
<Route path="/subscribe" component={Subscribe} />
<Route path="/order:oId" component={Order} />
<Route path="/subscription:sId" component={Subscription} />
<Route path="/login" component={LogIn}/>
<Route path="/admin" component={Admin}/>
<Route path="/signup" component={SignUp}/>
<Route path="/reset" component={Reset}/>
<Route path="/account" component={Account}/>
<Route path="/verify/:token" component={Verify}/>
</Switch>
</BrowserRouter>
);
}
}
export default App;
this how you code split your react js app:
import React,{lazy,Suspense} from 'react'
const Child = lazy(()=>import('./ChildComponent'))
const Parent = ()=> <Suspense fallback={<Loader/>}><Child/></Suspense>
here is full detailed explanation : React Code splitting
I am having problems dividing my application and using several routers. I have a main router where it handles several small applications and in each mini application I want to manage its opportune routes. What am I failing?
What I want to do is when I receive the data of the request, redirect me to a new screen but I can not get it. Can anybody help me? Thank you
Example https://stackblitz.com/edit/react-c2tkgf?file=Hello.js
Routes.js
import { BrowserRouter } from 'react-router-dom'
import React from 'react'
import { Switch, Route } from 'react-router-dom'
import { AuthenticatedRoute } from 'components/authenticated-route'
import Clients from 'components/clients'
import { Login } from 'components/login'
import Home from './Home/Home'
const Routes = () => {
return (
<BrowserRouter>
<Switch>
<Route exact path="/" component={Home} />} />
<Route exact path="/clients" component={Clients} />
<Route exact path="/login" component={Login} />} />
</Switch>
</BrowserRouter>
)
}
export default Routes
Clients.js
import React, { Component } from 'react'
import { connect } from 'react-redux'
import Dashboard from './Dashboard/Dashboard'
import { Redirect, Route, Switch } from 'react-router-dom'
class Clients extends Component {
render() {
return (
<div>
<SearchCustomers />
{this.props.customer.token ? (
<div>
<Switch>
<Route path={`/clients:${this.props.customer.id}/dashboard`} component={Dashboard} />
</Switch>
<Redirect to={`/clients:${this.props.customer.id}/dashboard`} />
</div>
) : null}
</div>
)
}
}
const mapStateToProps = state => {
return {
customer: state.customer,
}
}
export default connect(mapStateToProps)(Clients)
In your Routes component you have:
<Route exact path="/clients" component={Clients} />
<Route exact path="/login" component={Login} />} />
since you have exact on there, those components will only be rendered when at exactly /clients or /login. in your built components, once you change the path, your parent component no longer renders, therefore nothing inside those components will render. remove the exact from your Routes:
<Rout path="/clients" component={Clients} />
<Rout path="/login" component={Login} />} />