I'm having a problem in getting the output of the "match" object value in this parameter routing code.
This is class where I use match:
import React from "react";
const ProductDetails = (props) => {
console.log(props.match);
return <h1>Details No. </h1>;
};
export default ProductDetails;
And the code I use for using the route is:
import React, { Component } from "react";
import NavBar from "./navbar";
import ProductDetails from "./productDetails";
class App extends Component {
render() {
return (
<React.Fragment>
<NavBar
productsCount={this.state.Product.filter((p) => p.count > 0).length}
/>
<main className="container">
<Routes>
<Route path="/about" element={<About />} />
<Route path="/" element={<Home />} />
<Route path="/contact" element={<Contact />} />
<Route
path="/cart"
element={
<ShoppingCart
products={this.state.Product}
onReset={this.resetData}
onIncrement={this.incrementEntry}
onDelete={this.deleteEntery}
/>
}
/>
<Route path="/products/:id" element={<ProductDetails />} />
</Routes>
</main>
</React.Fragment>
);
}
}
And I get the answer as "undefined" and a lot of red errors msgs.
if you are using react router v6 and what you want to do is getting the id, it would be:
import React from "react";
const ProductDetails = () => {
const {id} = useParams();
return <h1>Details No. {id}</h1>;
};
export default ProductDetails;
or if you really want the match object:
import React from "react";
const ProductDetails = () => {
const match = useMatch();
return <h1>Details No.</h1>;
};
export default ProductDetails;
What is element? If you use react-router-dom for routing you must set the component for any route.
<BrowserRouter>
<Route path ="/about" component= {<About />} />
<Route path ="/" component= {<Home/>}/>
<Route path ="/contact" component= {<Contact/>}/>
<Route path ="/cart" component= {<ShoppingCart
products= {this.state.Product}
onReset ={this.resetData}
onIncrement ={this.incrementEntry}
onDelete = {this.deleteEntery}/>}/>
<Route path="/products/:id" component={<ProductDetails />}/>
</BrowserRouter>
Related
So, I am trying to put a random component when the user refresh the page web. How can I do it? I created my components and tried to use it like an array but it shows the index of the array when i refresh the page. For example only show 0, 1 or 2 because I have 3 items in my DATA array. Could you help me please? Thank you so much!!!
import React, { useEffect, useState } from 'react';
import './App.css';
import Enterprice from './components/pages/Enterprice';
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import Developers from './components/pages/Developers';
import Community from './components/pages/Community';
import Download from './components/pages/Download';
import SignUp from './components/pages/SignUp';
import Marketing from './components/pages/Marketing';
import Consulting from './components/pages/Consulting';
import Navbar from './components/navbar/Navbar';
import { MainFrontOne } from './components/ui/mainFront/mainFrontOne/MainFrontOne';
import { MainFrontTwo } from './components/ui/mainFront/mainFrontTwo/MainFrontTwo';
import { MainFrontThree } from './components/ui/mainFront/mainFrontThree/MainFrontThree';
function App() {
const data =[
<MainFrontOne/>, <MainFrontTwo/>, <MainFrontThree/>
]
const [mainFrontRandom, setMainFrontRandom] = useState(null);
const compDisplay = ()=>{
const randomDisplay = Math.floor(Math.random()*data.length);
setMainFrontRandom(randomDisplay)
}
useEffect(() => {
compDisplay()
}, [])
return (
<>
<BrowserRouter>
<Navbar />
{/* <MainFrontOne/> */}
{/* <MainFrontTwo/> */}
{/* <MainFrontThree/> */}
{
mainFrontRandom
}
<Routes>
<Route path="/" element={<Enterprice />}/>
<Route path="enterprice" element={<Enterprice />}/>
<Route path="developers" element={<Developers />}/>
<Route path="community" element={<Community />}/>
<Route path="download" element={<Download />}/>
<Route path="sign-up" element={<SignUp />}/>
<Route path="marketing" element={<Marketing />}/>
<Route path="consulting" element={<Consulting />}/>
</Routes>
</BrowserRouter>
</>
);
}
export default App;
This is my third component and the others are similar.
import React from 'react';
import './mainFrontThree.css';
export const MainFrontThree = () => {
return (
<div >
<section className="main-front-section">
Hello world
</section>
</div>
)
}
You have two ways to fix this problem.
1. Set the mainFrontRandom to random component
const compDisplay = () => {
const randomDisplay = Math.floor(Math.random()*data.length);
setMainFrontRandom(randomDisplay)
}
)
}
2. Render the component from data and use index of mainFrontRandom
<>
<BrowserRouter>
<Navbar />
{/* <MainFrontOne/> */}
{/* <MainFrontTwo/> */}
{/* <MainFrontThree/> */}
{
data[mainFrontRandom] <--- this changed
}
<Routes>
<Route path="/" element={<Enterprice />}/>
<Route path="enterprice" element={<Enterprice />}/>
<Route path="developers" element={<Developers />}/>
<Route path="community" element={<Community />}/>
<Route path="download" element={<Download />}/>
<Route path="sign-up" element={<SignUp />}/>
<Route path="marketing" element={<Marketing />}/>
<Route path="consulting" element={<Consulting />}/>
</Routes>
</BrowserRouter>
</>
)
}
This example works fort me even when you reload. Look at the state, the component is there and not the number. Make sure you store the component in the state and not the index. Probably that is the issue with previous example.
import './App.css';
import { useEffect, useState } from 'react';
import MainFrontOne from './MainFrontOne';
import MainFrontTwo from './MainFrontTwo';
import MainFrontThree from './MainFrontThree';
function App() {
const data =[
<MainFrontOne/>, <MainFrontTwo/>, <MainFrontThree/>
]
const [mainFrontRandom, setMainFrontRandom] = useState(null);
const compDisplay = ()=>{
const randomDisplay = Math.floor(Math.random()*data.length);
setMainFrontRandom(data[randomDisplay])
}
useEffect(() => {
compDisplay()
}, [])
return (
<div className="App">
mainFrontRandom: {mainFrontRandom}
</div>
);
}
export default App;
I am trying to read the code but its returning undefined.
I want to read the code from the route and display it in h3 tag.
The Routing
<Router>
<Routes>
<Route path="/" element={<p>Homepage</p>} />
<Route path="/join" element={JoinRoomPage()} />
<Route path="/create" element={CreateRoomPage()} />
This is the roomCode i want to read in the Room Component
<Route path="/room/:roomCode" element={Room()} />
</Routes>
</Router>
The Room Component
import React, { useState, useEffect } from "react";
import { useParams } from "react-router-dom";
export default function Room(props) {
const [room, setRoom] = useState({
votesToSkip: 2,
guestCanPause: true,
isHost: false,
});
let { roomCode } = useParams();
return (
<div>
<h3>{roomCode}</h3>
<p>Votes: {room.votesToSkip}</p>
<p>Guest Can Pause: {room.guestCanPause}</p>
<p>Host: {room.isHost}</p>
</div>
);
}
Thanks in advance
The route components should be passed as JSX, not as an invoked function.
<Router>
<Routes>
<Route path="/" element={<p>Homepage</p>} />
<Route path="/join" element={<JoinRoomPage />} />
<Route path="/create" element={<CreateRoomPage />} />
<Route path="/room/:roomCode" element={<Room />} />
</Routes>
</Router>
Router
<Router>
<Routes>
<Route path="/" element={<p>Homepage</p>} />
<Route path="/join" element={JoinRoomPage()} />
<Route path="/create" element={CreateRoomPage()} />
This is the roomCode i want to read in the Room Component
<Route path="/room/:roomCode" element={<Room />} />
</Routes>
</Router>
Room Component
import { useState, useEffect } from "react";
import { useParams } from "react-router-dom";
const Room = (props) => {
let { roomCode } = useParams();
const [room, setRoom] = useState({
votesToSkip: 2,
guestCanPause: true,
isHost: false,
});
return (
<div>
<h3>{roomCode}</h3>
<p>Votes: {room.votesToSkip}</p>
<p>Guest Can Pause: {room.guestCanPause}</p>
<p>Host: {room.isHost}</p>
</div>
);
}
export default Room;
I'm using React Router v6 and am creating private routes for my application.
In file PrivateRoute.js, I've the code
import React from 'react';
import {Route,Navigate} from "react-router-dom";
import {isauth} from 'auth'
function PrivateRoute({ element, path }) {
const authed = isauth() // isauth() returns true or false based on localStorage
const ele = authed === true ? element : <Navigate to="/Home" />;
return <Route path={path} element={ele} />;
}
export default PrivateRoute
And in file route.js I've written as:
...
<PrivateRoute exact path="/" element={<Dashboard/>}/>
<Route exact path="/home" element={<Home/>}/>
I've gone through the same example React-router Auth Example - StackBlitz, file App.tsx
Is there something I'm missing?
I ran into the same issue today and came up with the following solution based on this very helpful article by Andrew Luca
In PrivateRoute.js:
import React from 'react';
import { Navigate, Outlet } from 'react-router-dom';
const PrivateRoute = () => {
const auth = null; // determine if authorized, from context or however you're doing it
// If authorized, return an outlet that will render child elements
// If not, return element that will navigate to login page
return auth ? <Outlet /> : <Navigate to="/login" />;
}
In App.js (I've left in some other pages as examples):
import './App.css';
import React, {Fragment} from 'react';
import {BrowserRouter as Router, Route, Routes} from 'react-router-dom';
import Navbar from './components/layout/Navbar';
import Home from './components/pages/Home';
import Register from './components/auth/Register'
import Login from './components/auth/Login';
import PrivateRoute from './components/routing/PrivateRoute';
const App = () => {
return (
<Router>
<Fragment>
<Navbar/>
<Routes>
<Route exact path='/' element={<PrivateRoute/>}>
<Route exact path='/' element={<Home/>}/>
</Route>
<Route exact path='/register' element={<Register/>}/>
<Route exact path='/login' element={<Login/>}/>
</Routes>
</Fragment>
</Router>
);
}
In the above routing, this is the private route:
<Route exact path='/' element={<PrivateRoute/>}>
<Route exact path='/' element={<Home/>}/>
</Route>
If authorization is successful, the element will show. Otherwise, it will navigate to the login page.
Only Route components can be a child of Routes. If you follow the v6 docs then you'll see the authentication pattern is to use a wrapper component to handle the authentication check and redirect.
function RequireAuth({ children }: { children: JSX.Element }) {
let auth = useAuth();
let location = useLocation();
if (!auth.user) {
// Redirect them to the /login page, but save the current location they were
// trying to go to when they were redirected. This allows us to send them
// along to that page after they login, which is a nicer user experience
// than dropping them off on the home page.
return <Navigate to="/login" state={{ from: location }} />;
}
return children;
}
...
<Route
path="/protected"
element={
<RequireAuth>
<ProtectedPage />
</RequireAuth>
}
/>
The old v5 pattern of create custom Route components no longer works. An updated v6 pattern using your code/logic could look as follows:
const PrivateRoute = ({ children }) => {
const authed = isauth() // isauth() returns true or false based on localStorage
return authed ? children : <Navigate to="/Home" />;
}
And to use
<Route
path="/dashboard"
element={
<PrivateRoute>
<Dashboard />
</PrivateRoute>
}
/>
Complement to reduce lines of code, make it more readable and beautiful.
This could just be a comment but I don't have enough points, so I'll
put it as an answer.
Dallin's answer works but Drew's answer is better! And just to complete Drew's answer on aesthetics, I recommend creating a private component that takes components as props instead of children.
Very basic example of private routes file/component:
import { Navigate } from 'react-router-dom';
const Private = (Component) => {
const auth = false; //your logic
return auth ? <Component /> : <Navigate to="/login" />
}
Route file example:
<Routes>
<Route path="/home" element={<Home />} />
<Route path="/user" element={<Private Component={User} />} />
</Routes>
I know that this is not exactly the recipe on how to make PirvateRoute work, but I just wanted to mention that the new documentation recommends a slightly different approach to handle this pattern with react-router v6:
<Route path="/protected" element={<RequireAuth><ProtectedPage /></RequireAuth>} />
import { Navigate, useLocation } from "react-router";
export const RequireAuth: React.FC<{ children: JSX.Element }> = ({ children }) => {
let auth = useAuth();
let location = useLocation();
if (!auth.user) {
return <Navigate to="/login" state={{ from: location }} />;
}
return children;
};
And you are supposed to add more routes inside ProtectedPage itself if you need it.
See the documentation and an example for more details. Also, check this note by Michael Jackson that goes into some implementation details.
Just set your router component to element prop:
<Routes>
<Route exact path="/" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="/dashboard" element={<Dashboard />} />
</Routes>
You can also check for upgrading from v5.
Remove the PrivateRoute component from your project and use the following code in your App.js files:
import {Navigate} from "react-router-dom";
import {isauth} from 'auth'
...
<Route exact path="/home" element={<Home/>}/>
<Route exact path="/" element={isauth ? <Dashboard/> : <Navigate to="/Home" />}/>
It's 2022 and I did something like below:
// routes.tsx
import { lazy } from "react";
import { Routes, Route } from "react-router-dom";
import Private from "./Private";
import Public from "./Public";
const Home = lazy(() => import("../pages/Home/Home"));
const Signin = lazy(() => import("../pages/Signin/Signin"));
export const Router = () => {
return (
<Routes>
<Route path="/" element={Private(<Home />)} />
<Route path="/signin" element={Public(<Signin />)} />
</Routes>
);
};
// Private.tsx
import { Navigate } from "react-router-dom";
import { useEffect, useState } from "react";
function render(c: JSX.Element) {
return c;
}
const Private = (Component: JSX.Element) => {
const [hasSession, setHasSession] = useState<boolean>(false);
useEffect(() => {
(async function () {
const sessionStatus = await checkLoginSession();
setHasSession(Boolean(sessionStatus));
})();
}, [hasSession, Component]);
return hasSession ? render(Component) : <Navigate to="signin" />;
};
export default Private;
Hope this helps!
React Router v6, some syntactic sugar:
{auth && (
privateRoutes.map(route =>
<Route
path={route.path}
key={route.path}
element={auth.isAuthenticated ? <route.component /> : <Navigate to={ROUTE_WELCOME_PAGE} replace />}
/>
)
)}
I tried all answers, but it always displayed the error:
Error: [PrivateRoute] is not a component. All component children of must be a or <React.Fragment>
But I found a solution ))) -
In PrivateRoute.js file:
import React from "react"; import { Navigate } from "react-router-dom";
import {isauth} from 'auth'
const PrivateRoute = ({ children }) => {
const authed = isauth()
return authed ? children : <Navigate to={"/Home" /> };
export default ProtectedRoute;
In the route.js file:
<Route
path="/"
element={
<ProtectedRoute >
<Dashboard/>
</ProtectedRoute>
}
/>
<Route exact path="/home" element={<Home/>}/>
Children of Routes need to be Route elements, so we can change the ProtectedRoute:
export type ProtectedRouteProps = {
isAuth: boolean;
authPath: string;
outlet: JSX.Element;
};
export default function ProtectedRoute({
isAuth,
authPath,
outlet,
}: ProtectedRouteProps) {
if (isAuth) {
return outlet;
} else {
return <Navigate to={{pathname: authPath}} />;
}
}
And then use it like this:
const defaultProps: Omit<ProtectedRouteProps, 'outlet'> = {
isAuth: //check if user is authenticated,
authPath: '/login',
};
return (
<div>
<Routes>
<Route path="/" element={<ProtectedRoute {...defaultProps} outlet={<HomePage />} />} />
</Routes>
</div>
);
This is the simple way to create a private route:
import React from 'react'
import { Navigate } from 'react-router-dom'
import { useAuth } from '../../context/AuthContext'
export default function PrivateRoute({ children }) {
const { currentUser } = useAuth()
if (!currentUser) {
return <Navigate to='/login' />
}
return children;
}
Now if we want to add a private route to the Dashboard component we can apply this private route as below:
<Routes>
<Route exact path="/" element={<PrivateRoute><Dashboard /></PrivateRoute>} />
</Routes>
For longer elements
<Router>
<div>
<Navbar totalItems={cart.total_items}/>
<Routes>
<Route exact path='/'>
<Route exact path='/' element={<Products products={products} onAddToCart={handleAddToCart}/>}/>
</Route>
<Route exact path='/cart'>
<Route exact path='/cart' element={<Cart cart={cart}/>}/>
</Route>
</Routes>
</div>
</Router>
Header will stay on all page
import React from 'react';
import {
BrowserRouter,
Routes,
Route
} from "react-router-dom";
const Header = () => <h2>Header</h2>
const Dashboard = () => <h2>Dashboard</h2>
const SurveyNew = () => <h2>SurveyNew</h2>
const Landing = () => <h2>Landing</h2>
const App = () =>{
return (
<div>
<BrowserRouter>
<Header />
<Routes >
<Route exact path="/" element={<Landing />} />
<Route path="/surveys" element={<Dashboard />} />
<Route path="/surveys/new" element={<SurveyNew/>} />
</Routes>
</BrowserRouter>
</div>
);
};
export default App;
<Route path='/' element={<Navigate to="/search" />} />
You can use a function for a private route:
<Route exact path="/login" element={NotAuth(Login)} />
<Route exact path="/Register" element={NotAuth(Register)} />
function NotAuth(Component) {
if (isAuth)
return <Navigate to="/" />;
return <Component />;
}
I'm using "react-router-dom": "^6.3.0" and this is how I did mine
PrivateRoute Component and Route
import {Route} from "react-router-dom";
const PrivateRoute = ({ component: Compontent, authenticated }) => {
return authenticated ? <Compontent /> : <Navigate to="/" />;
}
<Route
path="/user/profile"
element={<PrivateRoute authenticated={true} component={Profile} />} />
For the error "[Navigate] is not a <Route> component. All component children of <Routes> must be a <Route> or <React.Fragment>", use the following method maybe solved:
DefaultPage is when no match router. Jump to the DefaultPage. Here use the <Route index element={} /> to replace the
<Navigate to={window.location.pathname + '/kanban'}/>
See Index Routes
<Routes>
<Route path={'/default'} element={<DefaultPage/>}/>
<Route path={'/second'} element={<SecondPage/>}/>
{/* <Navigate to={window.location.pathname + '/kanban'}/> */}
<Route index element={<DefaultPage/>} />
</Routes>
import { BrowserRouter as Router, Routes, Route, Link } from "react-router-dom";
function App() {
return (
<Router>
<Routes>
<Route path="/" element={<h1>home page</h1>} />
<Route path="/seacrch" element={<h1>seacrch page</h1>} />
</Routes>
</Router>
);
}
export default App;
I am trying to upgrade to React Router v6 (react-router-dom 6.0.1).
Here is my updated code:
import { BrowserRouter, Navigate, Route, Routes } from 'react-router-dom';
<BrowserRouter>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/lab" element={<Lab />} />
<Route render={() => <Navigate to="/" />} />
</Routes>
</BrowserRouter>
The last Route is redirecting the rest of paths to /.
However, I got an error
TS2322: Type '{ render: () => Element; }' is not assignable to type 'IntrinsicAttributes & (PathRouteProps | LayoutRouteProps | IndexRouteProps)'. Property 'render' does not exist on type 'IntrinsicAttributes & (PathRouteProps | LayoutRouteProps | IndexRouteProps)'.
However, based on the documentation, it does have render for Route. How can I use it correctly?
I think you should use the no match route approach.
Check this in the documentation: Adding a "No Match" Route
import { BrowserRouter, Navigate, Route, Routes } from 'react-router-dom';
<BrowserRouter>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/lab" element={<Lab />} />
<Route
path="*"
element={<Navigate to="/" replace />}
/>
</Routes>
</BrowserRouter>
To keep the history clean, you should set replace prop. This will avoid extra redirects after the user click back.
I found another way to do this:
import { useNavigate } from "react-router-dom";
let navigate = useNavigate();
useEffect(() => {
if (LoggedIn){
return navigate("/");
}
},[LoggedIn]);
See Overview, Navigation.
Create the file RequireAuth.tsx
import { useLocation, Navigate } from "react-router-dom";
import { useAuth } from "../hooks/Auth";
export function RequireAuth({ children }: { children: JSX.Element }) {
let { user } = useAuth();
let location = useLocation();
if (!user) {
return <Navigate to="/" state={{ from: location }} replace />;
} else {
return children;
}
}
Import the component to need user a private router:
import { Routes as Switch, Route } from "react-router-dom";
import { RequireAuth } from "./RequireAuth";
import { SignIn } from "../pages/SignIn";
import { Dashboard } from "../pages/Dashboard";
export function Routes() {
return (
<Switch>
<Route path="/" element={<SignIn />} />
<Route
path="/dashboard"
element={
<RequireAuth>
<Dashboard />
</RequireAuth>
}
/>
</Switch>
);
}
In version 5 of React, i.e., react-router-dom, we had the Redirect component. But in version 6 of React it is updated to the Navigate components.
We can pass replace in these components to avoid unnecessary redirects on clicking back and forward option.
Demonstration for usage is attached below:
<Route path="/" element={user ? <Home /> : <Register />} />
<Route path="/login" element={user ? <Navigate to="/" replace /> : <Login />} />
<Route path = "/register" element={user ? <Navigate to="/" replace /> : <Register />} />
FOR react-router VERSION 6
New example after editing----->(more simple easy to read)
import {BrowserRouter as Router,Routes,Route} from 'react-router-dom';
import Home from '../NavbarCompo/About';
import Contact from '../NavbarCompo/Contact';
import About from '../NavbarCompo/About';
import Login from '../NavbarCompo/Login';
import Navbar from '../Navbar/Navbar';
import Error from '../pages/error';
import Products from '../pages/products';
import Data from '../NavbarCompo/Data';
const Roter=()=>{
return (
<Router>
<Navbar />
<Routes>
<Route path='/' element={<Home />} />
<Route path='/about' element={<About />} />
<Route path='/contact' element={<Contact />} />
<Route path='/login' element={<Login />} />
<Route path='/product/:id' element={<Products />} />
<Route path='/data' element={<Data />} />
<Route path ='*' element={<Error />} />
</Routes>
</Router>
)
}
export default Roter;
Look at the example
import React from "react";
import Form from "./compo/form";
import ReactDOM from "react-dom/client";
import { createBrowserRouter, RouterProvider, Route,Routes,Navigate } from "react-router-dom";
const router = createBrowserRouter([
{
path: "/",
element: <Form />
},
{
path: "/about",
element: <h1>hola amigo,you are in about section</h1>
},
{
path:"*",
element:<Navigate to="/" replace />
}
]);
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<React.StrictMode>
<RouterProvider router={router}></RouterProvider>
</React.StrictMode>
);
check this out
https://reactrouter.com/en/main/start/overview
<BrowserRouter>
<Routes>
<Route path="home" element={<Home />} />
<Route path="about" element={<About />} />
<Route index element={<Navigate to="/home" replace />} />
</Routes>
</BrowserRouter>
import { useNavigate } from "react-router-dom";
import { Button } from "#mui/material";
const component =()=>{
const navigate = useNavigate();
const handelGoToLogin = () => {
navigate('/auth/login')
}
return(<>
//.........
<Button onClick={handelGoToLogin} variant="outlined" color="primary" size="large" fullWidth>
Back
</Button>
</>)
}
import { useState } from "react"
import { Navigate } from "react-router-dom"
const [login, setLogin] = useState(true)
return (<>
{!login && <Navigate to="/login" />}
<>)
For class components, at the first you should make a functional component, and then use HOC technical to use useNavigate React hook.
Like this:
File withrouter.js
import {useNavigate} from 'react-router-dom';
export const withRouter = WrappedComponent => props => {
return (<WrappedComponent {...props} navigate={useNavigate()}/>);
};
Then use it in other class components like this:
export default withRouter(Signin);
And use props for redirect like this:
this.props.navigate('/');
My routes file is getting rather messy so I decided to split them out into separate files.
My problem is that if I used 2 separate files, whichever comes after the first include does not get rendered:
const routes = (
<div>
<Switch>
<Route exact path="/" component={Home} />
{Registration} //Does get rendered
//Everything below this does not get a route
{Faq}
<Route path="/login" component={login} />
<Route component={NoMatch} />
</Switch>
</div>
);
If I switch Faq with registration then all the Faq routes will work.
RegistrationRoutes.js
import Introduction from '../containers/Registration/Introduction';
import Login from '../containers/Login';
const Routes = (
<Switch>
<Route path="/login" component={Login} key="login" />,
<Route path="/registration/introduction" component={Introduction} key="registration-intro" />
</Switch>
);
export default Routes;
FaqRoutes.js
import Faq from '../containers/Faq';
import faqJson from '../json_content/faq/faq';
import FaqCategory from '../containers/Faq/faqCategory';
const Routes = (
<Switch>
<Route path="/faq/:category" component={FaqCategory} key="faqCat" />
<Route path="/faq" render={props => <Faq data={faqJson} />} key="faq" />
</Switch>
);
export default Routes;
May be you can move them to config file and load them from there.
App.tsx
import routes from "./routes";
const App: React.FC = () => {
return (
<BrowserRouter>
<div>
<Switch>
{routes.data.map((entry) => {return (<Route {...entry}/>)})}
</Switch>
</div>
</BrowserRouter>
);
};
export default App;
router.ts
const routes = {data: [
{
key: "one",
path: "/three"
},
{
key: "two",
path: "/two"
}
]
}
export default routes;
This will keep your code simple
Your code would get translated to something like this,
const routes = (
<div>
<Switch>
<Route exact path="/" component={Home} />
<Switch>
<Route path="/login" component={Login} key="login" />,
<Route path="/registration/introduction"
component={Introduction} key="registration-intro" />
</Switch>
//Everything below this does not get a route
{Faq}
<Route path="/login" component={login} />
<Route component={NoMatch} />
</Switch>
</div>
);
This is wrong way to implement routing with react-router-dom or React-Router v4.
For Correct way of implementation You can see this example.
index.js
import React from "react";
import ReactDOM from "react-dom";
import { BrowserRouter, Switch, Route, Link } from "react-router-dom";
import LandingPage from "../Registration";
const Home = () => {
return <div>
Home Component
<Link to="/auth/login">Login</Link>
</div>;
};
function App() {
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
<BrowserRouter>
<Switch>
<Route exact path="/" component={Home} />
<Route path="/auth" component={LandingPage} />
</Switch>
</BrowserRouter>
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Registration.js
import React, { Component } from 'react';
import { Switch, Route, Link, Redirect } from 'react-router-dom';
const LoginRegister = (props) => {
return (
<div>
Login or register
<Link to="/login">Login</Link>
<br />
<Link to="/signup" >Signup</Link>
</div>
);
}
const Login = (props) =>{
console.log("login ", props);
return (
<div>
Login Component
<Link to="/auth/signup" >Signup</Link>
</div>
);
}
const Signup = () => (
<div>
Signup component
<Link to="/auth/login" >Login</Link>
</div>
);
class LandingPage extends Component {
render() {
console.log('Landing page',this.props);
const loginPath = this.props.match.path +'/login';
const signupPath = this.props.match.path + '/signup';
console.log(loginPath);
return (
<div className="container" >
Landing page
<Switch>
<Route path={loginPath} component={Login} />
<Route path={signupPath} component={Signup} />
<Route path="/" exact component={LoginRegister} />
</Switch>
</div>
);
}
}
export default LandingPage;
Try the following
RegistrationRoutes.js
import Introduction from '../containers/Registration/Introduction';
import Login from '../containers/Login';
const Routes = (
<React.Fragment>
<Route path="/login" component={Login} key="login" />,
<Route path="/registration/introduction" component={Introduction} key="registration-intro" />
</React.Fragment>
);
export default Routes;