Costomize React Routing with Switch Statement - javascript

I am building a react app where two different Usergroups sign in (via Firebase).
Each Usergroup needs to get a different Routing. The different groups should share urls but with different content.
To do so I have added a switch statement to routes js.
When I change acctype manually the code works like expected, but I need to change the acctype var out of my firebaseclass in order to route the right person to the right route...
The problem is, that react renders the view before any setter Method can set the acctype variable. I have tried it with callbacks and .done and asnyc as well.
This routes.js exports the components with the variable rut directly into the index.js React.dom.render()
Thank you for your help!
import {Route, Router, IndexRedirect, browserHistory} from 'react-
router';
var acctype = 0;
var rut = "";
switch (acctype) {
case 0: //Group0
rut = (
<Router history={browserHistory}>
<Route path="/" component={Blank}>
<IndexRedirect to="/welcome"/>
<Route path="welcome" component={Welcome_View}></Route>
<Route path="login" component={Login_View}></Route>
<Route path="*" component={fofView}></Route>
</Route>
</Router>
);
break;
case 1: //Group1
rut = (
<Router history={browserHistory}>
<Route path="/" component={Main}>
<IndexRedirect to="/uebersicht"/>
<Route path="uebersicht" component={Uebersicht_KtppView}></Route>
<Route path="wiki" component={Wiki_KtppView}></Route>
<Route path="netzwerk" component={Netzwerk_KtppView}></Route>
<Route path="meineEinrichtung" component={meineEinrichtung_KtppView}></Route>
<Route path="feedback" component={Feedback_KtppView}></Route>
</Route>
</Router>
);
break;
case 2: //Group 2
rut = (
<Router history={browserHistory}>
<Route path="/" component={Main}>
<IndexRedirect to="/main"/>
<Route path="main" component={MainView}></Route>
<Route path="minor" component={MinorView}></Route>
</Route>
</Router>
);
break;
}
export default(rut)

I have found a new idea to solve this problem
the onEnter attribute does the work
It is described in the last tipp
https://scotch.io/tutorials/routing-react-apps-the-complete-guide

Related

React Router v6 always render "/"

I'm trying to implement router in react-create-app but it always render "/" and showing Home or SignIn page. How can I solve this?
function AppRouter({ isLoggedIn, user }) {
return(
<Router>
<Routes>
<Route path="/profile" element={<Profile />} />
<Route path="/signUp" element={<SignUp />} />
{isLoggedIn
? <Route exact path={"/"} element={<Home user={user}/>} />
: <Route exact path={"/"} element={<SignIn />} />
}
</Routes>
</Router>
)
}
It seems you have a slight misunderstanding of how the HashRouter works with the UI.
import { HashRouter as Router, Route, Routes } from "react-router-dom";
import Profile from "./Profile";
import SignUp from "./SignUp";
import Home from "./Home";
export default function App() {
return (
<Router>
<Routes>
<Route path="/profile" element={<Profile />} />
<Route path="/signUp" element={<SignUp />} />
<Route path="/" element={<Home />} />
</Routes>
</Router>
);
}
The HashRouter handles routing with a URL hash value, i.e. everything after the "#" in the URL. If you are trying to render your app and access "<domain>/" instead of "<domain>/#/" the routing won't work.
For example in your running codesandbox demo, the base URL is "https://5p7hff.csb.app/". At this base URL the hash router isn't really working, and you should really be accessing "https://5p7hff.csb.app/#/" instead so the hash router is loaded and the app's internal routing can work.
From "https://5p7hff.csb.app/#/" you should be to then navigate to any of your routes, i.e. "https://5p7hff.csb.app/#/profile" and https://5p7hff.csb.app/#/signUp".
If you switch to a different router, like the BrowserRouter then the "/#/" is no longer used, the router and routes render from "/" where the app is running from. The routes would be "https://5p7hff.csb.app/", "https://5p7hff.csb.app/profile", and "https://5p7hff.csb.app/signUp".

How to separate routes inside a React App

I have the following on my index.js
<Router routes={routes} />
I would like to have routes section in a separate file, so far I tried this:
routes.js
export default (
<div>
<Route path="/" component={AppComponent}>
<Route path="/someother" component={AddProductComponent} />
</Route>
<Route path="/products" component={ListProductComponent} />
</div>
);
and in index.js
import routes from './routes';
<Router routes={routes} />
For some reason the app shows blank now. looks like the routes are not rendered.
UPDATE, this is my whole index.js except missing imports due stackoverflow companing about too much code put:
const rootReducer = combineReducers({
products: productReducer,
});
const store = createStore(
rootReducer,
applyMiddleware(thunk),
);
ReactDOM.render(
<Provider store={store}>
<Router routes={routes} />
</Provider>
, document.getElementById('root')
);
Update routes.js
export default (
<Switch>
<Route exact path="/" component={AppComponent}/>
<Route path="/products" component={ListProductComponent}>
<Route path="/details/:productId" component={AddProductComponent} />
</Route>
</Switch>
);
You're missing the switch:
<Switch>
<Route path="/someother" component={AppComponent}>
<Route path="/products" component={ListProductComponent} />
<Route path="/" component={AppComponent}>
</Switch>
Also, your code will only show AppComponent, as any url (/, /home, /etc) starts with the slash you put in the path attribute. You might want that as a last page, a fallback.
The path attribute works with a wildcare: path="/" -> path="/**" are functionally the same. If you want an exact path, add exact to the Route.
If you mean to split routes into seperate files, you can do this:
<Switch>
<Route path={"/user"} component={UserRouter}/>
<Route path={"/product"} component={ProductRouter}/>
</Switch>
// In userRouter.jsx:
export function UserRouter() {
return <Switch>
<Route exact path={"/user/list"} component={UserListPage}/>
<Route exact path={"/user/signup"} component={userSignupPage}/>
<Route exact path={"/user/profile"} component={UserProfilePage}/>
</Switch>
};

`react-router` warning solution and passing root props to sub routes

Sometime I was sawing the well known warning, browser.js:49 Warning: [react-router] You cannot change <Router routes>; it will be ignored and I found two trend issues that friends discussed about this issue and the solution is const routes components and putting them inside Router component.
https://github.com/ReactTraining/react-router/issues/2704
https://github.com/reactjs/react-router-redux/issues/179
Just like below:
you will see warning with this code:
class Root extends Component {
render() {
return (
<Router history={browserHistory} createElement={this.createElement}>
<Route component={App}>
<Route path="/" component={MainPage}/>
<Route path="/page2" component={Page2}/>
<Route path="/settings" component={SettingsPage}/>
</Route>
</Router>
)
}
}
but you won't see warning with this code:
const routes = (
<Route component={App}>
<Route path="/" component={MainPage}/>
<Route path="/page2" component={Page2}/>
<Route path="/settings" component={SettingsPage}/>
</Route>
);
class Root extends Component {
render() {
return (
<Router history={browserHistory} createElement={this.createElement}>
{routes}
</Router>
)
}
}
This is OK, awesome solution to vanish [react-router] warning, and for Root Component changing state the routes was static and you won't see any warnings. BUT my issue is: I pass Root Component props to each Route and I can not do the above solution 😞 ,
I must put App Route inside Router so with this method absolutely this is not solution method and I will saw the known warning again, see my router code:
export default class AppRoutes extends Component {
render() {
return (
<Router history={hashHistory}>
<Route path="/" {...this.props} component={App}>
<IndexRoute component={Home} {...this.props}/>
<Route path="/transaction" component={Transaction} {...this.props}/>
<Route path="/users-management" component={UsersManagement} {...this.props}/>
<Route path="/issues" component={Issues} {...this.props}/>
<Route path='/not-found' component={NotFound}/>
<Route path='/settlement-management' component={SettlementManagement} {...this.props}/>
<Route path='/categories-management' component={CategoriesManagement} {...this.props}/>
<Route path='/gifts-management' component={GiftsManagement} {...this.props}/>
<Redirect from='/*' to='/not-found'/>
</Route>
</Router>
);
}
}
And the Root Component render code is:
render(){
return(
<AppRoutes {...this}/>
);
}
I passed this as a props to AppRoutes component and I need to pass inherited this.props to sub Routes and use them. how I could won't see warning and pass props to any Routes?
One of my solution is that, I write all Routes as static and call Root Component props directly inside each component, but how? I don't know how I can call and keep props of Root Component inside the component that need to have props of Root Component as the component is not direct Root Component children?
You can use render route prop instead of component to pass props to your components :
<Route path="/transaction" render={() => <Transaction {...this.props} />} />
Edit : Or this to also pass route props :
<Route path="/transaction" render={(routeProps) => <Transaction parentProps={this.props} {...routeProps} />} />
(I think it's better to pass individual custom parent props to not enter in conflict with routeProps)

React-Router can't make subroutes

Maybe somebody know why I can create subroutes
My code.
<Provider store={store}>
<Router history={history}>
<Route path="/" component={Main} >
<IndexRoute component={Home} />
<Route path="performance" component={Performance} />
<Route path="home" component={Home} >
<Route path="alert" component={Performance} />
</Route>
</Route>
</Router>
</Provider>
// ...
// imports
import Main from './Main'
import Performance from './performance/PerformanceComponent'
import Home from './home/HomeComponent'
import {Router, Route, IndexRoute} from 'react-router'
import {Provider} from 'react-redux'
I can't go to this address -> /home/alert
And Have this errors in console
alert:11 GET http://0.0.0.0:3001/home/css/style.css
alert:12 GET ...home/css/home.css
alert:13 GET ...home/css/detailsView.css
alert:26 GET ...home/bundle.tvc.js
I mean if I write wrong address I have special error
Warning: [react-router] Location "/homealert" did not match any routes
I don't have any idea how should I fix it. Thank you in advance!
You want this if you want to Performance component to render on /home/alert. You need to specify the complete path on each matching Routes.
<Route path="/" component={Main} >
<IndexRoute component={Home} />
<Route path="/performance" component={Performance} />
<Route path="/home" component={Home} >
<Route path="/home/alert" component={Performance} />
</Route>
</Route>
Nesting routes applies to components, not paths. Your app will render as below for /home/alert:
<Main>
<Home>
<Performance>

React router get currently active segment as param

I have following router configuration
<Router history={history}>
<Route path="/" component={ReviewWizard}>
<IndexRoute component={Administrative}/>
<Route path="Administrative" component=Administrative}>
<Route path="/Administrative/:itemId" component={AdministrativeItem}/>
</Route>
<Route path="Offense" component={Offense}/>
</Route>
</Router>
I'm trying to get currently active route segment (ie Administrative or Offense).
Is there a way to do something like this? ie route constraints
<Router history={history}>
<Route path="/:segment" component={ReviewWizard}>
<IndexRoute component={Administrative}/>
<Route path="/:segment=Administrative/:itemId" component={Administrative}>
<Route path="/Administrative/:itemId" component={AdministrativeItem}/>
</Route>
<Route path="/:segment=Offense" component={Offense}/>
</Route>
</Router>
If not, what is best practice to get the current active route segment? I don't like this.context.router.routes[1].path
First off I would recommend the following router config, as it seems that it's what you're aiming for:
<Router history={history}>
<Route path="/" component={ReviewWizard}>
<!-- whenever we hit '/' we redirect to '/Administrative' -->
<IndexRedirect path="/Administrative"/>
<!-- Renders ReviewWizard <- Administrative -->
<Route path="/Administrative" component={Administrative}>
<!-- Renders ReviewWizard <- Administrative <- AdministrativeItem -->
<Route path="/Administrative/:itemId" component={AdministrativeItem}/>
</Route>
<!-- Renders ReviewWizard <- Offense -->
<Route path="/Offense" component={Offense}/>
</Route>
</Router>
As for detecting the currently active route (or if a route fragment is active), I would recommend using the router.isActive -method. Simply do something like this:
if (router.isActive('/Administrative')) {
doSomething()
} else if (router.isActive('/Offense')) {
doSomethingElse()
}
For something more declarative, I recommend just using the location object that react-router injects into each component it manages:
const { location: { pathname } } = this.props
const [ activeSegment ] = pathname.slice(1).split('/')
Hope these help!

Categories

Resources