I have a situation where on onClick funtion which should push to path :'/trains/alerts-list' which actually happens but it renders under this url component TrainAlertsList which is correct, but below it's rendering also TrainDetailsScreen which is not correct. I have onClick function like below :
Which creates url path of TrainsListAlerts:
TrainsAlertsList: {
path: '/trains/alerts-list',
name: 'Trains alerts list',
viewName: 'TRAINS_ALERTS_LIST',
},
TrainDetails: {
path: '/trains/:idTrain',
name: 'Train details',
viewName: 'TRAIN_DETAILS',
},
routingManager.tsx file looks like:
const TrainsAlertsListScreen = lazy(() =>
import('@nevomo/trains').then((module) => ({
default: module.TrainsAlertsList,
}))
const TrainDetailsScreen = lazy(() =>
import('@nevomo/trains').then((module) => ({
default: module.TrainDetailsScreen,
}))
);
<ProtectedRoute
requiredRoles={[
ROLES.vehicleOperator,
ROLES.vehicleAnalyst,
]}
isAuth={isLogin}
exact
path={[
Routes.Trains.path,
Routes.TrainsMap.path,
Routes.TrainDetails.path,
Routes.TrainHistory.path,
Routes.TrainService.path,
Routes.TrainWheels.path,
Routes.TrainsAlertsList.path,
]}
>
);
<ProtectedRoute
requiredRoles={[
ROLES.vehicleOperator,
ROLES.vehicleAnalyst,
]}
isAuth={isLogin}
path={Routes.TrainsAlertsList.path}
Component={TrainsAlertsListScreen}
exact
/>
<ProtectedRoute
requiredRoles={[
ROLES.vehicleOperator,
ROLES.vehicleAnalyst,
]}
isAuth={isLogin}
path={Routes.TrainDetails.path}
Component={TrainDetailsScreen}
exact
/>
index.ts with all exports:
export * from './lib/trains';
export * from './lib/components/map/map';
export * from './views/train-details/train-details';
export * from './views/train-history/train-history';
export * from './views/train-service/train-service';
export * from './views/train-wheels/train-wheels';
export * from './views/train-wheels/components/train-wheels-details/train-wheels-details';
export * from './views/train-wheels/components/train-wheels-faults/train-wheels-faults';
export * from './lib/components/trains-alerts-list/trains-alerts-list';
And component:
import { Toolbar } from '@nevomo/common-components'; import { FC } from 'react';
export const TrainsAlertsList: FC = () => {
return (
<div>
<Toolbar />
<div>działa</div>
</div>
);
};
Can You please look at it and let me know what is causing that TrainDetailsScreen is rendered although it's not called ? And how to fix it ?
thanks a lot !
CodePudding user response:
These 2 routes match the same thing. /trains/alerts-list
is the same as trains/:id
or use the exact
attribute in the Route
component (This is not the case if you are using react-router v6). You should change one of them. Try with trains/:id/details
TrainsAlertsList: {
path: '/trains/alerts-list',
name: 'Trains alerts list',
viewName: 'TRAINS_ALERTS_LIST',
},
TrainDetails: {
path: '/trains/:idTrain',
name: 'Train details',
viewName: 'TRAIN_DETAILS',
},
CodePudding user response:
Both these components match and render on the Routes.TrainDetails.path
(i.e. "/trains/:idTrain"
) path. Since both are being rendered then I'll assume you are rendering your routes into a Router
and not within a Switch
. If you are wanting only a single route to match and be rendered render them into the Switch
component.
The Switch
differs from the Router
in that a Router
inclusively renders all matching routes by path whereas the Switch
exclusively renders only the first match. In the Switch
path order and specificity matter! You want to order the paths from more specific paths to less specific, so matching and rendering can work properly.
'/trains/alerts-list'
is more specific than '/trains/:idTrain'
and should be rendered higher/before.
Example:
<Router>
...
<Switch>
.... other more specific "/trains/alerts-list/...." routes
<ProtectedRoute
requiredRoles={[
ROLES.vehicleOperator,
ROLES.vehicleAnalyst,
]}
isAuth={isLogin}
path={Routes.TrainsAlertsList.path} // '/trains/alerts-list'
Component={TrainsAlertsListScreen}
/>
.... other more specific "/trains/...." routes
<ProtectedRoute
requiredRoles={[
ROLES.vehicleOperator,
ROLES.vehicleAnalyst,
]}
isAuth={isLogin}
path={Routes.TrainDetails.path} // '/trains/:idTrain'
Component={TrainDetailsScreen}
/>
.... other less routes
</Switch>
...
</Router>