Я пытаюсь превратить блок жестко закодированных <Route />
во что-то, что динамически генерируется из переменной конфигурации.Например:
С
<Router>
<Switch>
<Route path="/" component={Home} exact />
<Route path="/about" component={About} />
<Route path="/documents" component={Documents} exact />
<Route path="/documents/faq" component={DocFAQ} />
<Route path="/documents/translations" component={Translations} />
</Switch>
</Router>
До
const routes = [
{
path: '/',
component: Home,
exact: true
},
{
path: '/about',
component: About
},
{
path: '/documents',
component: Documents,
children: [
{
path: '/faq',
component: DocFAQ
},
{
path: '/translations',
component: Translations
}
]
}
];
const RecursiveRoute = ({ route, parentPath = '' }) => {
const path = parentPath + route.path;
return (
<React.Fragment>
<Route path={path} exact={route.exact || (route.children != null)} component={route.component} />
{route.children && route.children.map((childRoute, i) => <RecursiveRoute key={i} route={childRoute} parentPath={path} />)}
</React.Fragment>
);
};
const Routes = () => (
<Router>
<Switch>
{routes.map((route, i) => <RecursiveRoute key={i} route={route} />)}
</Switch>
</Router>
);
Этот код генерирует именно то, что я хочу, когда я принимаю вызов отображения вне <Router>
;например.Я могу убедиться, что он выводит точно такой же код, как и у ранее закодированного блока.Однако когда он находится внутри <Switch>
, отображается только первый маршрут в массиве routes
- больше ничего не генерируется.Помещение операторов логирования в <RecursiveRoute>
подтверждает это.
Почему это так и как это исправить?
Еще одна странная вещь заключается в том, что, если я вставлю <RecursiveRoute>
JSX прямо в map
оператор, он работает (за исключением того, что я не могу сделать его рекурсивным в этом случае):
<Switch>
{routes.map((route, i) => <Route key={i} path={route.path} exact={route.exact || (route.children != null)} component={route.component} />)}
</Switch>
Но если я оставлю это на стороне другого компонента, сопоставление снова не будет выполнено.
[Редактировать] Решение:
На основании ответа Мехамасума , изменение <RecursiveRoute>
из компонента в функцию решило эту проблему:
function generateRecursiveRoute(route, parentPath = '') {
const path = parentPath + route.path;
const routeHasChildren = (route.children != null);
const baseHtml = <Route path={path} exact={route.exact || routeHasChildren} component={route.component} key={path} />;
return !routeHasChildren ?
baseHtml :
<React.Fragment key={path}>
{baseHtml}
{route.children.map((childRoute) => generateRecursiveRoute(childRoute, path))}
</React.Fragment>;
}
const Routes = () => (
<Router>
<Switch>
{routes.map((route) => generateRecursiveRoute(route))}
</Switch>
</Router>
);