【问题标题】:ReactJS route URL generating by config配置生成的 ReactJS 路由 URL
【发布时间】:2026-02-05 03:00:01
【问题描述】:

假设我有这个应用程序代码

const Menu = () => {
    return (
        <nav>
            <Link to="/">Home</Link>
            <Link to="/contact">Contact</Link>
            <Link to="/about">Contact</Link>
        </nav>
    )
};

const App = () => {
    return (
        <Router>
            <div>
                <Menu/>
                <Route exact path="/" component={Home} />
                <Route path="/contact" render={() =>
                    <h1>Contact</h1>
                } />
                <Route path="/about" render={() =>
                    <h1>About</h1>
                } />
            </div>
        </Router>
    );
};

export default App;

我只想知道如何使路由路径成为非静态路径并将整个路由树基于某种配置。

假设我想将/about 路由路径更改为/about_us。在这种情况下,我需要在整个项目中搜索/about 字符串并正确替换它。当项目相当大时,这将不是乐观的方式。

如果我有一些存储在常量中的路由配置和某种函数,它会根据路由名称和查询参数等数据生成整个路径。例如:

const ROUTES = {
    home : '/',
    page: '/page/:pageid',
    about: '/about'
};

const url = (routeName, routeParams) => {
    // here generate route for particular route name
};

然后我可以像这样更改我的 JSX:

<Link to={ url('contact') }>Contact</Link>

因此,随着ROUTES 常量的更改,使用url() 函数生成的所有路由路径也将更改。

我的问题是:
对于这类问题有什么好的现有解决方案/实践/模式/包

(顺便说一句。刚刚学习 ReactJS)

然后出现另一个问题。 ReactJS 应用程序的模块化是什么。如何将路由配置划分为仅存储在特定模块中(例如:在“博客”模块中发布路由配置)。

【问题讨论】:

标签: javascript reactjs react-router react-jsx


【解决方案1】:

为什么不自己写呢?简单的可能是这样的

// CLASS
class AppRoutes {
    constructor(routes) {
        this.routes = routes;
    }

    path(name) {
        return this.routes[name]
    }

    to(name, ...params) {
        const regex = /:[^\/:]+/;
        let path = this.routes[name],
            i = 0,
            result;
        while(result = regex.exec(path)) {
            path = path.replace(result[0], params[i])
            i++
        }
        return path;
    }
}


// USAGE
var appRoutes = new AppRoutes({
    home: '/',
    about: '/about',
    post: '/posts/:byUser/:id',
})

console.log( 
  appRoutes.path('about') 
)

console.log(
  appRoutes.to('post', 'John', 'somepostId')
)

【讨论】:

  • 我当然想过这个。需要问这种解决方案是否存在,不要从头再写(如果没有)^^。第二件事是标准和最佳实践——作为一个 React 初学者不太了解——最好从一开始就使用正确的东西:)。感谢您的回答。
【解决方案2】:

我知道为时已晚,但以防万一有人想要使用 react-router 的强类型版本:

import { generatePath } from "react-router";

const generateRoutes = (routes) => {
  return Object.keys(routes).reduce((agg, next) => {
    agg[next] = {
      path: routes[next],
      to: (params) => generatePath(routes[next], params)
    };
    return agg;
  }, {});
};

export const Routes = generateRoutes({
  home: "/",
  contactUs: "/contact-us",
  blogPost: `/blog-post/:id`,
  products: `/products/:category(A|B|C)/:sort(ASC|DESC)?`,
});

console.log(Routes.home.path) // outputs: /
console.log(Routes.contactUs.to()) // outputs: /contact-us
console.log(Routes.products.to({category: "A", sort: "ASC"})) // outputs: /products/A/ASC

【讨论】: