All components are loaded at once even after using lazy load - javascript

I am trying to lazy load some pages which should load after login. But I can see in the devtools the pages are still being loaded at once with the main bundle.
Before adding lazy load option, I could see the minimized bundle size was 874 KB. After the lazy loaded option is added, the size is still the same.
here's the code:
import { LandingPage, ErrorPage } from "./pages";
import {
createBrowserRouter,
createRoutesFromElements,
Route,
RouterProvider,
} from "react-router-dom";
import RouteLayout from "./layout/RouteLayout";
import { lazy, Suspense } from "react";
//Lazy loading components
const RestaurantPage = lazy(() => import("./pages/RestaurantPage"));
const CartPage = lazy(() => import("./pages/CartPage"));
const ContactPage = lazy(() => import("./pages/ContactPage"));
const AccountDetails = lazy(() => import("./pages/AccountDetails"));
function App() {
//Routing elements
const router = createBrowserRouter(
createRoutesFromElements(
<Route path="/" element={<RouteLayout />} errorElement={<ErrorPage />}>
<Route index element={<LandingPage />} />
<Route
path="/order"
element={
<Suspense fallback={<h1>Loading...</h1>}>
<RestaurantPage />
</Suspense>
}
/>
<Route
path="/cart"
element={
<Suspense fallback={<h1>Loading...</h1>}>
<CartPage />
</Suspense>
}
/>
<Route
path="/contact"
element={
<Suspense fallback={<h1>Loading...</h1>}>
<ContactPage />
</Suspense>
}
/>
<Route
path="/myAccount"
element={
<Suspense fallback={<h1>Loading...</h1>}>
<AccountDetails />
</Suspense>
}
/>
</Route>
)
);
return (
<ChakraProvider>
<RouterProvider router={router} />
</ChakraProvider>
);
}
export default App;
Should I be adding any other memory optimization to make it work?

Related

React Protected Route Not Working in My App.js --- v6 [duplicate]

This question already has answers here:
How to create a protected route with react-router-dom?
(5 answers)
Closed 4 months ago.
Help
I'm using a protected route in my React app. But it is not working. All the other Elements are working but when I got to "/account" the whole screen is white. This is my code. It will be really helpful for me if you give that answer. Thank You :)
Protected Route code:
import React, { Fragment } from 'react';
import { useSelector } from 'react-redux';
import { Route, Routes, redirect } from 'react-router-dom';
const ProtectedRoute = ({ element: Element, ...rest }) => {
const { loading, isAuthenticated, user } = useSelector(state => state.user);
return (
<Fragment>
{!loading &&
(<Routes>
<Route
{...rest}
render={(props) => {
if(!isAuthenticated) {
return redirect("/login")
}
return <Element {...props} />
}}
/>
</Routes>
)}
</Fragment>
)
}
export default ProtectedRoute;
I am using ProtectedRoute.js in App.js. Here is the code.
App.js Code:
import React from 'react';
import {BrowserRouter as Router,Route,Routes} from "react-router-dom";
import './App.css';
import Header from "./component/layout/Header/Header.js";
import webFont from "webfontloader";
import Footer from './component/layout/Footer/Footer';
import Home from "./component/Home/Home.js";
import ProductDetails from "./component/Product/ProductDetails.js";
import Products from "./component/Product/Products.js";
import Search from "./component/Product/Search.js";
import LoginSignUp from './component/User/LoginSignUp';
import store from "./store";
import { loadUser } from './action/userAction';
import UserOption from "./component/layout/Header/UserOption.js";
import { useSelector } from 'react-redux';
import Profile from "./component/User/Profile.js"
import ProtectedRoute from './component/Route/ProtectedRoute';
function App() {
const {isAuthenticated, user} = useSelector(state => state.user)
React.useEffect(() => {
webFont.load({
google:{
families:["Roboto","Droid Sans","Chilanka"]
},
});
store.dispatch(loadUser())
}, [])
return (
<Router>
<Header />
{isAuthenticated && <UserOption user={user} />}
<Routes>
<Route path="/" element={<Home />} />
<Route path="/product/:id" element={<ProductDetails />} />
<Route path="/products" element={<Products />} />
<Route path="/products/:keyword" element={<Products />} />
<Route path="/search" element={<Search />} />
<Route path="/account" element={ <ProtectedRoute> <Profile /> </ProtectedRoute> } />
<Route path="/login" element={<LoginSignUp />} />
</Routes>
<Footer />
</Router>
);
}
export default App;
In your App.js you can declare the protected route like this
<Route path="/account" element={ <ProtectedRoute /> } >
<Route path="/account" element={ <Profile /> } >
</Route>
You can use Outlet of react-router v6 for passing the Component
const ProtectedRoute = ({ element: Element, ...rest }) => {
const { loading, isAuthenticated, user } = useSelector(state => state.user);
if (loading) {
return <h2>Loading...</h2>
}
return isAuthenticated ? <Outlet /> : <Navigate to="/login" />;
}
# Sayedul Karim.
I have a better and more concise way for this, An example of the code is below.
<Routes>
<Route element={<App />}>
{isAuthenticated ? (
<>
<Route path="/*" element={<PrivateRoutes />} />
<Route
index
element={<Navigate to="/account" />}
/>
</>
) : (
<>
<Route path="auth/*" element={<AuthPage />} />
<Route path="*" element={<Navigate to="/auth" />} />
</>
)}
</Route>
</Routes>
In this way, you don't have to make any private component instead just make a component for private routes where the routes are defined.
The PrivateRoutes component will be like this
<Routes>
<Route>
{/* Redirect to account page after successful login */}
{/* Pages */}
<Route path="auth/*" element={<Navigate to="/account" />} />
<Route path="account" element={<Account />} />
</Routes>
If any query further, feel free to ask....
I'm not sure, but you haven't pass any "element" prop to your ProtectedRoute component. You pass Profile component as children, so try render children instead of element in ProtectedRoute if you want your code to work like this.
I believe that you might want not to nest those routes, so also you might want to try use ProtectedRoute as Route in your router, I'm talking about something like this
<Routes>
...
<ProtectedRoute path="/account" element={<Profile />} />
...
</Routes>
UPDATE
It might show you this error because your Route is conditionally rendered, so try to handle loading state in some other way, maybe something like this
return (
<Route
{...rest}
render={(props) => {
if(!isAuthenticated) {
return redirect("/login")
}
if(loading) {
return <LoadingComponent />
}
return <Element {...props} />
}}
/>
)

I'm getting blank react-app page on using Route

I'm having some kind of trouble when I'm using Router in App.js
I'm getting a blank page when I am using, I tried a lot but couldn't found a way to solve the issue.
<GuestRoute path="/Authenticate" element={<Authenticate />}>
</GuestRoute>
it is working fine with
<Route path="/Authenticate" element={<Authenticate />}>
</Route>
but I have to use GuestRoute.
Given below is the whole code:
App.js
import "./App.css";
import {BrowserRouter as Router, Routes, Route, Navigate } from "react-router-dom";
import React from "react"
import Navigation from "./components/shared/Navigation/Navigation";
import Home from "./Pages/Home/Home";
import Register from "./Pages/Register/Register";
import Login from "./Pages/Login/Login";
import Authenticate from "./Pages/Authenticate/Authenticate";
const isAuth = true;
function App() {
return (
<div className="App">
<Router>
<Navigation />
{/* switch(prev. versions) ----> Routes (new versions)) */}
<Routes>
<Route exact path="/" element={<Home />} >
</Route>
<GuestRoute path="/Authenticate" element={<Authenticate />}>
</GuestRoute>
</Routes>
</Router>
</div>
);
}
const GuestRoute = ({children,...rest}) => {
return(
<Route {...rest}
render={({location})=>{
return isAuth ? (
<Navigate to={{
pathname: '/rooms',
state: {from: location}
}}
/>
):(
children
);
}}
></Route>
);
};
export default App;
react-router-dom#6 doesn't use custom route components. The new pattern used in v6 are either wrapper components or layout route components.
Wrapper component example:
const GuestWrapper = ({ children }) => {
... guest route wrapper logic ...
return (
...
{children}
...
);
};
...
<Router>
<Navigation />
<Routes>
<Route path="/" element={<Home />} />
<Route
path="/Authenticate"
element={(
<GuestWrapper>
<Authenticate />
</GuestWrapper>
)}
/>
</Routes>
</Router>
Layout route component example:
import { Outlet } from 'react-router-dom';
const GuestLayout = () => {
... guest route wrapper logic ...
return (
...
<Outlet /> // <-- nested routes render here
...
);
};
...
<Router>
<Navigation />
<Routes>
<Route path="/" element={<Home />} />
<Route element={<GuestLayout>}>
<Route path="/Authenticate" element={<Authenticate />} />
... other GuestRoute routes ...
</Route>
</Routes>
</Router>

Error: [undefined] is not a <Route> component. All component children of <Routes> must be a <Route> or <React.Fragment> [duplicate]

This question already has answers here:
ReactJS: [Home] is not a <Route> component. All component children of <Routes> must be a <Route> or <React.Fragment>
(5 answers)
Closed 10 months ago.
I'm trying to upgrade the react-router-dom from v5 to v6 but I am getting this error message.
Error: [undefined] is not a <Route> component. All component children of <Routes> must be a <Route> or <React.Fragment>
Anyone please help me with this issue.
index.js file code
import React from "react"
import ReactDOM from "react-dom"
import "./assets/main.css"
import App from "./App"
import { BrowserRouter } from "react-router-dom"
import { AuthContextProvider } from "./context/AuthContext"
ReactDOM.render(
<React.StrictMode>
<AuthContextProvider>
<BrowserRouter>
<App />
</BrowserRouter>
</AuthContextProvider>
</React.StrictMode>,
document.getElementById("root")
)
App.js file code
import React, { Suspense } from "react"
import { Routes, Route } from "react-router-dom"
import "./App.css"
import { Helmet } from "react-helmet"
// custom components
import SideBar from "./components/layouts/SideBar"
import Navbar from "./components/layouts/Navbar"
import Footer from "./components/layouts/Footer"
import Feedback from "./components/feedback/Feedback"
import useGaTracker from "./hooks/useGaTracker"
import LottieAnimation from "./components/smallComponents/LottieAnimation"
// loader
import rocketLoader from "./assets/animated_illustrations/loader.json"
// lazy loading components
const Dashboard = React.lazy(() => import("./components/dashboard/Dashboard"))
const ChallengesList = React.lazy(() => import("./components/challenges/ChallengesList"))
const ChallengeDetails = React.lazy(() =>
import("./components/challenges/ChallengeDetails")
)
const Resources = React.lazy(() => import("./components/resources/Resources"))
const Roadmaps = React.lazy(() => import("./components/roadmaps/Roadmaps"))
const SolutionList = React.lazy(() => import("./components/solutions/SolutionList"))
const MySolutions = React.lazy(() => import("./components/MySolutions/MySolutions"))
const App = () => {
useGaTracker()
return (
<>
<Helmet>
<title>CODINGSPACE - Learn by Building Web and Mobile Apps</title>
</Helmet>
<div className="relative grid min-h-screen md:grid-cols-layout-tablet xl:grid-cols-layout-desktop grid-rows-layout-desktop md:gap-6">
<Navbar />
<SideBar />
<Suspense
fallback={
<div className="sm:ml-0 pr-5 py-52 row-start-2 row-end-3 col-start-1 md:col-start-2 col-end-3 place-self-center">
<LottieAnimation
animationDataFile={rocketLoader}
height={100}
width={100}
/>
</div>
}
>
<Routes>
<Route exact path="/">
<Dashboard />
</Route>
<Route path="/challenges">
<ChallengesList />
</Route>
<Route path="/challenge/:id">
<ChallengeDetails />
</Route>
<Route path="/resources">
<Resources />
</Route>
<Route path="/roadmaps">
<Roadmaps />
</Route>
<Route path="/solutions">
<SolutionList />
</Route>
<Route path="/mysolutions">
<MySolutions />
</Route>
</Routes>
</Suspense>
<Feedback />
<Footer />
</div>
</>
)
}
export default App
You should pass the component as "element", like:
<Route path="/" element={<Dashboard/>}>
Or for protected routes:
<Route
path="home"
element={
<ProtectedRoute user={user}>
<Home />
</ProtectedRoute>
}
/>
...
</Routes>

How to write/create a private route in react-router-dom v6?

I tried creating a private route using react-router-dom v6 as shown below in React JS
import React from 'react';
import {BrowserRouter as Router, Routes, Route} from 'react-router-dom';
import * as ROUTES from './constants/routes';
import { Home, Signin, Signup, Browse } from './pages';
import { IsUserRedirect, ProtectedUserRedirect } from './helpers/routes';
function App() {
const user=null;
return (
<>
<Router>
<Routes>
<Route exact path={ROUTES.HOME} element={<IsUserRedirect user={user} path={ROUTES.BROWSE} />}>
<Route element={<Home />} />
</Route>
<Route exact path={ROUTES.BROWSE} element={<ProtectedUserRedirect user={user} path={ROUTES.SIGN_IN} />}>
<Route element={<Browse />} />
</Route>
<Route exact path={ROUTES.SIGN_IN} element={<IsUserRedirect user={user} path={ROUTES.BROWSE} />}>
<Route element={<Signin />} />
</Route>
<Route exact path={ROUTES.SIGN_UP} element={<IsUserRedirect user={user} path={ROUTES.BROWSE} />}>
<Route element={<Signup />} />
</Route>
</Routes>
</Router>
</>
);
}
export default App;
and the helper components are implemented as shown below
import React from 'react';
import { Navigate, Outlet } from 'react-router-dom';
export const IsUserRedirect = ({path, user, children}) => {
console.log(Boolean(user))
return (
user?<Navigate to={path} replace />:<Outlet />
)
}
export const ProtectedUserRedirect = ({path, user, children}) => {
console.log(Boolean(user))
return (
user?<Outlet />:<Navigate to={path} replace />
)
}
NO ERROR AT TERMINAL AND CONSOLE but I'm not getting any output. The components seems to not rendering properly. Could you please me how to write better private route in v6 of router-dom. Reference: https://dev.to/iamandrewluca/private-route-in-react-router-v6-lg5
THANKS IN ADVANCE

I need you to redirect to Shop if url is wrong. React js

I need it to redirect to my main page if the url is wrong, the problem must be in this part , because before I used Redirect, but in the new version of React it is Navigate and I don't know if the way of entering changed
import React from 'react';
import {Routes, Route, Navigate} from 'react-router-dom';
import {authRoutes, publicRoutes} from '../routes';
import { SHOP_ROUTE } from '../utils/consts';
const AppRouter = () => {
const isAuth = false
return (
<Routes>
{isAuth && authRoutes.map(({path, Component}) =>
<Route key={path} path={path} element={<Component/>} exact/>
)}
{publicRoutes.map(({path, Component}) =>
<Route key={path} path={path} element={<Component/>} exact/>
)}
<Navigate to={SHOP_ROUTE}/>
</Routes>
);
};
export default AppRouter;
If you include a <Route path="*" /> component (as shown in the docs) at the end of the <Routes />, then the last route will be shown when no other route has been matched.
import React from 'react';
import {Routes, Route, Navigate} from 'react-router-dom';
import {authRoutes, publicRoutes} from '../routes';
import { SHOP_ROUTE } from '../utils/consts';
const AppRouter = () => {
const isAuth = false
return (
<Routes>
{isAuth && authRoutes.map(({path, Component}) =>
<Route key={path} path={path} element={<Component/>} exact/>
)}
{publicRoutes.map(({path, Component}) =>
<Route key={path} path={path} element={<Component/>} exact/>
)}
<Route path="*" element={<NotFound />} />
</Routes>
);
};
export default AppRouter;

Categories