我有一个全局JSON配置,它具有各种配置数据,包括路由名称和我希望为路由呈现的组件。我想从这个JSON配置动态构建我的路由。我现在能够动态生成路由,但是,由于路径组件是JSON文件中的字符串,React不喜欢它们并抛出下面的错误。有关实现这一目标的任何建议吗?
warning.js:44 Warning: Unknown props `history`, `location`, `params`, `route`, `routeParams`, `routes` on <Dashboard> tag. Remove these props from the element. For details, see https://f b.me/react-unknown-prop
in Dashboard
in RouterContext
in Router
相关的JSON代码段:
{
"routes" : [
{
"route_name" : "home",
"path" : "/",
"visible_in_menu" : true,
"menu_title" : "Home",
"menu_font_awesome_icon" : "fa fa-home",
"component" : "App",
"child_routes" : null
},
{
"route_name" : "analytics",
"path" : "/analytics",
"visible_in_menu" : true,
"menu_title" : "Analytics",
"menu_font_awesome_icon" : "fa fa-bar-chart",
"component" : "Dashboard",
"template" : null,
"child_routes" : [
{
"route_name" : "analytics_daily" ,
"path" : "/daily",
"visible_in_menu" : true,
"menu_title" : "Daily",
"component" : "Dashboard"
}
]
}
]
}
获取配置并动态构建路由的代码:
import React from 'react';
import ReactDOM from 'react-dom';
import { Router, Route, Link, browserHistory } from 'react-router'
import $ from 'jquery';
import App from './App';
import Dashboard from './Dashboard';
import SidebarMenu from './SidebarMenu';
import './index.css';
$.get("/routes_menu_config.json", bootstrapApplication);
function bootstrapApplication(config){
var dynamicRoutesJSX = buildDynamicRoutes(config);
// Add dynamic routes to app
ReactDOM.render((
<Router history={browserHistory}>
{dynamicRoutesJSX}
</Router>
), document.getElementById('root'));
// Render sidebar menu
ReactDOM.render(
<SidebarMenu />,
document.getElementById('menu')
);
}
function buildDynamicRoutes(config){
var routeJSX = [];
for (let [index, route] of config.routes.entries()) {
routeJSX.push(<Route path={route.path} components={route.component} key={index}/>);
}
return routeJSX;
}
我还尝试了普通对象实例化路由而不是使用JSX,但它产生了同样的错误:
$.get("/routes_menu_config.json", bootstrapApplication);
function bootstrapApplication(config){
var dynamicRoutesJSX = buildDynamicRoutes(config);
// Add dynamic routes to app
ReactDOM.render(<Router history={browserHistory} routes={dynamicRoutesJSX}
// Render sidebar menu
ReactDOM.render(
<SidebarMenu />,
document.getElementById('menu')
);
}
function buildDynamicRoutes(config){
var routes = [];
// Iterate parent routes from config
for (var i=0; i<config.routes.length; i++) {
var configParentRouteDefinition = config.routes[i];
// Create parent route definition
var parentRouteDefinition = {
path : configParentRouteDefinition.path,
component: configParentRouteDefinition.component
};
// If there are child routes, add them to the definition
if(configParentRouteDefinition.child_routes){
// Track child routes
var childRoutes = [];
// Iterate child routes, generate definition
for(var j=0; j<configParentRouteDefinition.child_routes.length; j++){
var configChildRouteDefinition = configParentRouteDefinition.child_routes[j]
var childRouteDefinition = {
path : configChildRouteDefinition.path,
component: configChildRouteDefinition.component
};
childRoutes.push(childRouteDefinition);
}
// Ad the definition to the parent route definition
parentRouteDefinition["childRoutes"] = childRoutes;
}
routes.push(parentRouteDefinition);
}
return routes;
}
答案 0 :(得分:4)
您需要创建组件注册表,以便从名称中查找组件引用:
import App from './App';
import Dashboard from './Dashboard';
const componentRegistry = {
"App": App,
"Dashboard": Dashboard
}
<Route path={route.path} components={componentRegistry[route.component]} key={index}/>;
答案 1 :(得分:1)
如果您使用例如Webpack可以在不导入所有组件的情况下获得您想要的结果。但是,您必须将路径传递给组件而不是组件的名称。像这样:
json file:
{"nav": [
{
"label": "HOME",
"route": {
"url": "/",
"exact": true
},
"component": {
"path": "home",
"name": "home"
}
}}
createRoutes() {
return this.props.data.nav.map((item: any, index: number) => {
let DynamicComponent = require('../../' + item.component.path + '/' + item.component.name).default;
return <Route key={index} path={item.route.url}
exact={item.route.exact}
render={() => (<DynamicComponent key={item.component.name}/>)}/>
});
}
答案 2 :(得分:-1)
这个为我工作
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;