React

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript类库 > React > React根据配置生成路由

React根据配置生成路由的示例代码

作者:新星_

React路由看似只能由Route组件包裹组件的结构来构成,但是其实也可以通过编写路由数组配置然后通过数组循环来生成Route组件包裹组件的结构,所以本文给大家介绍了React根据配置生成路由的方法,需要的朋友可以参考下

根据配置生成路由

React路由看似只能由Route组件包裹组件的结构来构成,但是其实也可以通过编写路由数组配置然后通过数组循环来生成Route组件包裹组件的结构。

安装依赖react-router-dom,这是React中用于处理路由的库

npm install react-router-dom

创建路由配置

创建一个路由配置文件,其中定义了一个路由数组,包含各个路由的路径、组件等信息

// src/router/index.js
const routes = [
    {
        path: '/', // 路由路径
        component: () => import('./views/Home'), // 路由对应的组件
        exact: true
    },
    {
        path: '/about',
        component: () => import('./views/About'),
    },
    {
        path: '/contact',
        component: () => import('./views/Contact'),
    },
    // 可以添加更多的路由配置...
];

export default routes;

exact 属性用于指定路由匹配是否需要完全精确匹配路径。当 exact 设置为 true 时,只有当URL与path属性完全一致时,对应的路由组件才会被渲染。如果没有设置 exact 或者设置为 false,那么只要URL包含path指定的路径,该路由就会被认为匹配,进而渲染相应的组件。

假设有以下两个路由配置:

<Routes>
  <Route path="/" element={<Home />} exact />
  <Route path="/user/:id" element={<UserProfile />} />
</Routes>

两个路由都是使用 exact: true时:

当访问 / 时,只有 Home 组件会被渲染。 当访问 /user/123 时,只有 UserProfile 组件会被渲染。

不使用 exactexact: false时:

当访问 / 时,Home 组件会被渲染。 当访问 /user/123 时,由于 /user/:id 包含了 /,所以 Home 和 UserProfile 两个组件都会被渲染。如果没有设置 exact,React Router 认为 //user/:id 的一部分。

通常情况下,对于首页(通常是根路径 /),需要使用 exact: true,以避免其他路径(如 /user/:id)也匹配到根路径,导致不必要的组件渲染。而对于其他具体的路径,则不需要设置 exact,因为它们通常已经足够具体,不会引起混淆。

代码中使用了import()函数来异步加载组件,这样就实现了按需加载,有助于提高应用的性能。

也可以使用lazyHook懒加载的写法,如下所示:

// src/router/index.js
import React, { lazy } from 'react'
// 懒加载路由
const Home = lazy(()=>import("./views/Home"))
const About = lazy(()=>import("./views/About"))
const routes = [
  {
    path: '/',
    component: Home
  },
  {
    path: '/about',
    component: About
  },
  {
        path: '/contact',
        component: lazy(() => import('./views/Contact')),
   },
]
export default routes

动态生成路由

在项目的主应用文件(如App.jsx)中,使用react-router-dom提供的<Routes><Route>组件,结合上面的配置来动态生成路由。

// src/App.jsx
import React from 'react';
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import routes from './router/index.js';

function App() {
  return (
    <Router>
      <Routes>
        {routes.map((route, index) => (
          <Route
            key={index}
            path={route.path}
            element={<route.component />}
            exact={route.exact}
          />
        ))}
      </Routes>
    </Router>
  );
}

export default App;

element={<route.component />},它会根据路由数组配置中数组元素的component属性来加载对应的组件。

也可以在main.jsx文件中使用<Router>包裹根组件

// src/main.jsx
import React from 'react'; // 用于创建组件的
import { createRoot } from 'react-dom/client'; // 用于渲染页面的
import { Provider } from 'react-redux';
import store from './store/index.js';
import App from './App.jsx';
import { BrowserRouter} from 'react-router-dom';
createRoot(document.getElementById('root')).render(
    <Provider store={store}>
        <BrowserRouter>
            <App />
      </BrowserRouter>
    </Provider>
)

使用lazyHook懒加载路由组件时,需要在App.js中,为所有懒加载的组件提供了一个错误边界或加载状态

// src/App.jsx
import React, { Suspense } from 'react';
import { Routes, Route } from 'react-router-dom';
import routes from './router/index.js';

function App() {
  return (
     <Suspense fallback={<div>Loading...</div>}>
        <Routes>
          {routes.map((route, index) => (
            <Route
              key={index}
              path={route.path}
              element={<route.component />}
              exact={route.exact}
            />
          ))}
        </Routes>
     </Suspense>
  );
}

export default App;

还可以将配置的路由数组循环动态生成路由的代码抽离成一个单独的函数

// src/router/createRoute.js
import React from 'react';
import { Route } from 'react-router-dom';
// 接受一个路由数组
const createRoute = (routes) => {
    return routes.map((route,index) => {
        return (
            <Route
                key={index}
                path={route.path}
                element={<route.component />}
                exact={route.exact}
            />
        )
    })
}
export default createRoute;
// src/App.jsx
import React, { Suspense } from 'react';
import { Routes, Route } from 'react-router-dom';
import routes from './router/index.js';
import createRoute from './router/createRoute.js'

function App() {
  return (
     <Suspense fallback={<div>Loading...</div>}>
        <Routes>
          {
              createRoute(routes)
          }
        </Routes>
     </Suspense>
  );
}

export default App;

配置路由中包含子路由

目录结构:

创建一个路由配置文件,其中定义了各个路由及其子路由的信息,使用懒加载来优化性能

// src/router/index.js
import React from 'react';

const routes = [
    {
        path: '/',
        component: React.lazy(() => import('./views/Home')),
        exact: true,
    },
    {
        path: '/dashboard',
        component: React.lazy(() => import('./views/Dashboard')),
        children: [
            {
                path: 'users',
                component: React.lazy(() => import('./views/Users')),
            },
            {
                path: 'settings',
                component: React.lazy(() => import('./views/Settings')),
            },
        ],
    },
    {
        path: '/about',
        component: React.lazy(() => import('./views/About')),
    },
    {
        path: '/contact',
        component: React.lazy(() => import('./views/Contact')),
    },
];

export default routes;

动态生成路由的方法,为了处理懒加载组件的加载状态,需要添加<Suspense>组件

// src/router/createRoute.js
import React from 'react';
import { Route } from 'react-router-dom';
import { Suspense } from 'react'
const renderRoutes = (routes) => {
    return routes.map((route, index) => {
        // 当前路由配置项 route 包含 children 属性,递归调用 renderRoutes 函数来处理子路由
        if (route.children) {
            return (
                <Route
                    key={index}
                    path={route.path}
                    element={
                        <Suspense>
                            <route.component />
                        </Suspense>
                    }
                    exact={route.exact}
                >
                    {renderRoutes(route.children)}
                </Route>
            );
        }
        return (
            <Route
                key={index}
                path={route.path}
                element={<route.component />}
                exact={route.exact}
            />
        );
    });
};
export default renderRoutes;
// src/main.jsx
import React from 'react'; // 用于创建组件的
import { createRoot } from 'react-dom/client'; // 用于渲染页面的
import { Provider } from 'react-redux';
import store from './store/index.js';
import App from './App.jsx';
import { BrowserRouter} from 'react-router-dom';
createRoot(document.getElementById('root')).render(
    <Provider store={store}>
        <BrowserRouter>
            <App />
      </BrowserRouter>
    </Provider>
)
// src/App.jsx
import React, { Suspense } from 'react';
import { Routes, Route } from 'react-router-dom';
import routes from './router/index.js';
import renderRoutes from './router/createRoute.js'

function App() {
  return (
     <Suspense>
        <Routes>
          {
              renderRoutes(routes)
          }
        </Routes>
     </Suspense>
  );
}

export default App;

为了在父组件中正确显示子路由的内容,需要在父组件中使用<Outlet>组件。<Outlet>组件用于渲染嵌套的子路由。

// src/views/Dashboard/index.jsx
import { Outlet,Link } from 'react-router-dom'
import React from 'react';
const Dashboard = () => {
    return (
        <>
            <h1>Dashboard 页面</h1>
            <nav>
                <ul>
                    <li><Link to="/dashboard/users">Users</Link></li>
                    <li><Link to="/dashboard/settings">Settings</Link></li>
                </ul>
            </nav>
            <Outlet />
        </>
    )
}
export default Dashboard;

以上就是React根据配置生成路由的示例代码的详细内容,更多关于React根据配置生成路由的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文