从JSON动态定义ReactJS路由

k3bvogb1  于 2022-12-26  发布在  React
关注(0)|答案(4)|浏览(125)

我有一个全局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;

}
oknwwptz

oknwwptz1#

您需要创建一个组件注册表,以便可以从组件名称查找组件引用:

import App from './App'; 
import Dashboard from './Dashboard';

const componentRegistry = {
    "App": App,
    "Dashboard": Dashboard
}

<Route path={route.path} components={componentRegistry[route.component]} key={index}/>;
gj3fmq9x

gj3fmq9x2#

如果您使用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}/>)}/>
    });
}
fcg9iug3

fcg9iug33#

你不需要把事情复杂化。使用下面的方法。
React v.18和路由器为6.5.0

import React from 'react';
import Home from  './home.js';
import About from  './about.js';
import Contact from  './contact';
const Navigation = [
    {   
        id : 1,
        name: 'home',
        url : '/',
        element : <Home />,
    },
    {
        id : 2, 
        name: 'About',
        url : '/about',
        element : <About />,
    },
    {
        id : 3, 
        name: 'Contact',
        url : '/contact',
        element : <Contact />,
    },  
];
export default Navigation;

import React from 'react';
import {BrowserRouter as Router, Link, Routes, Route}  from 'react-router-dom';
import Navigation from './JSON';
import Home from  './home';
function Paths(){
    let paths = Navigation.map((paths) => (<li key={paths.id}><Link to={paths.url}>{paths.name}</Link></li>));  
    return(<>
        <ul>
            {paths}
        </ul>
    </>);
}
function Routing(){
    const routers = Navigation.map((paths) => 
        <Route key={paths.id} path={paths.url} element = {paths.element}></Route>); 
    return(<>
        <Router>
            <Paths />
            <Routes> 
                {routers}
            </Routes>               
        </Router>
    </>);
}

export default Routing;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
2eafrhcq

2eafrhcq4#

这个对我很有效
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;

相关问题