How to create seperate component just for routes using react router? - reactjs

like the title says I need to create separate component where I will store routes for my project. This is what I have done in App.js component:
<Router>
<Switch>
<Route path="/" exact />
<Route path="/messages/messagelist" exact />
<Route path="/messages/ceostats" exact />
<Route path="/resourcem/categories" exact />
<Route path="/resourcem/subcategories" exact />
<Route path="/resourcem/resources" exact />
<Route path="/surveys" exact />
<Route path="/userm/users" exact />
<Route path="/userm/usergroups" exact />
</Switch>
</Router>
What I need to do now, is to extract them for example in separate component let's call it Route.js. How do I do that?

I prefer to separate the RouterProvider in this way:
First, let create a RouterProvider.js:
import React from 'react';
import {BrowserRouter as Router, Switch, Route} from 'react-router-dom';
function RouterProvider() {
return (
<Router>
<Switch>
// Routes
</Switch>
</Router>
)
}
export default RouterProvider;
Now, create a routes.js file:
import HomePage from 'pages/home';
import AboutUsPage from 'pages/aboutUs';
const routes = [
{
path: '/home',
component: HomePage,
exact: true
},
{
path: '/aboutUs',
component: AboutUsPage,
exact: true
},
// and so on for other routes in your project
]
export default routes;
Back to the RouterProvder.js and import the routes object and use it:
import React from 'react';
import {BrowserRouter as Router, Switch, Route} from 'react-router-dom';
import routes from 'path/to/routes' // ---> import from routes.js file
function RouterProvider() {
return (
<Router>
<Switch>
{
routes.map(route =>
<Route path={route.path} component={route.component} exact={route.exact} />
)
}
</Switch>
</Router>
)
}
export default RouterProvider;
Finally, add the RouterProvider as the last layer in the App.js file:
import RouterProvider from 'path/to/providers/routerProvider'
function App() {
return (
<ReduxProvdier>
<RouterProvider/>
</ReduxProvider>
)
}
Note: ReduxProvider is just an example of other providers in your application like Toast provider or Network provider.
Note: creating routes object in routes.js is not useful in all cases for example if you wanna use Suspense/Lazy it's not working as your expectation.

<Route path="/" component = { ... } exact /> // read docs for more info
https://reactrouter.com/web/api/Route/component

Related

React component makes a white page

import React from 'react';
import { Switch, Route } from 'react-router-dom';
import Discussion from './discussion.js';
import Rules from './rules.js';
import Workflow from './workflow.js';
export default function() {
return (
<div>
hello
<Switch>
<Route exact path="/" component={Discussion} />
<Route exact path="/rules" component={Rules} />
<Route exact path="/workflow" component={Workflow} />
</Switch>
</div>
)
}
I'm importing the function called 'PageContent' from './page-content'
calling it with in app.js
Then the page goes blank

React Router Dom how to redirect to Other App.js route when you are in any subRoute of any route [duplicate]

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

Easy way to separate my protectedroute to different file in react

I am looking for a way to separate my protectedroute from a app.js. Everything works well in my code. But if the module become to big its hard to read and manage app.js
I am looking to separate my protected routes to some component so it works here very well.
My app.js right now look like this way
import React, { useState } from 'react';
import {
BrowserRouter as Router,
Switch,
Route,
Link,
useRouteMatch,
useParams,
HashRouter,
BrowserRouter,
Redirect
} from "react-router-dom";
import ReactDOM from 'react-dom';
//import useToken from './Routes/UseToken';
import Login from './Login/Login';
import Dashboard from './Dashboard/Dashboard';
import Customer from './Customer/Customer';
import ProtectedRoute from './Routes/ProtectedRoute';
function App() {
return (
<>
{/** use HasRouter but that will make # in the browser */}
{/*<HashRouter>*/}
<BrowserRouter basename='/invoice/webapps/'>
<Switch>
<Route path="/login"><Login /></Route>
<ProtectedRoute path="/dashboard"><Dashboard /></ProtectedRoute>
<ProtectedRoute path="/customer"><Customer/></ProtectedRoute>
<Route exact path="/"><Redirect exact from="/" to="dashboard" /></Route>
<Route path="*"><Redirect from="/" to="dashboard" /></Route>
</Switch>
</BrowserRouter>
{/** </HashRouter>*/}
{/** use HasRouter but that will make # in the browser */}
</>
);
}
export default App;
if (document.getElementById('app')) {
ReactDOM.render(<App />, document.getElementById('app'));
}
i want to separate these
<ProtectedRoute path="/dashboard"><Dashboard /></ProtectedRoute>
<ProtectedRoute path="/customer"><Customer/></ProtectedRoute>
You can create a file route.js export and object like this
const routes = [
{component: A, path: '/a'},
{component: B, path: '/b', isProtected: true}
]
and in App.js you can use routes.map(route => ()) for rendering them.
<BrowserRouter basename='/invoice/webapps/'>
{routes.map((route, index) =>
route.isProtected
? <ProtectedRoute path={route.path} key={index}><route.component/></ProtectedRoute>
: <Route path={route.path} key={index}><route.component/> </Route>
}
</BrowserRouter>
There may be some syntax errors, so I suggest you understanding my idea instead of copying.

React router not matching any route, always goes to 404 route

React router can't match any route and always shows last (NotFound) component. Everything works fine if I use BrowserRouter from 'react-router-dom' instead of Router. But I have to use Router because I have to use custom history (for which I am using history library). Heres my code.
import { Router, Route, Switch } from 'react-router-dom';
import { createBrowserHistory } from 'history';
import ExpenseDashboardPage from '../components/ExpenseDashboardPage';
import AddExpensePage from '../components/AddExpensePage';
import EditExpensePage from '../components/EditExpensePage';
import HelpPage from '../components/HelpPage';
import NotFound from '../components/NotFound';
import Header from '../components/Header';
import LoginPage from '../components/LoginPage';
export let history = createBrowserHistory();
function AppRouter() {
return (
<div>
<Router history={history}>
<Header />
<Switch>
<Route path="/" component={LoginPage} exact={true} />
<Route path="/dashboard" component={ExpenseDashboardPage} />
<Route path="/create" component={AddExpensePage} />
<Route path="/edit/:id" component={EditExpensePage} />
<Route path="/help" component={HelpPage} />
<Route component={NotFound} />
</Switch>
</Router>
</div>
);
}
export default AppRouter;
It looks like react-router-dom version 5.x is not compatible with history version 5.0.0. I switched to history version 4.x and now its working as expected.
I know this doesn't fit the question but in my case, i included a different component in Switch component. Switch component should only have Route components in them.

Sub routes at react router 4

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} />} />

Resources