具有react-router-4的路由组

时间:2017-12-08 18:59:58

标签: reactjs typescript react-router-v4

我的反应应用程序有3个重叠路径的入口点,并且很难维护。其中2个应用程序基本上只停留在旧网站的几个位置,直到主应用程序具有足够的功能来完全替换主站点。

我正在使用React路由器4,并且有一个包含所有路由的routes.tsx文件。但我想按功能对路由进行分组,然后让每个应用程序的路由组件只需要它所需要的。

目前我的路线如下:

const MainAppRoutes: React.SFC = (): JSX.Element =>
{
    return (
        <Switch>
            <Route exact path='/' component={HomePage} />
            <Route path='/customers' component={CustomersDisplayPage} />
            <Route path='/customers/:id' component={CustomersDisplayPage} />
            <Route path='/cars' component={CarDisplayPage} />
            <Route path='/cars/:id' component={CarDisplayPage} />
        </Switch>
    );
};

但我希望它看起来像这样:

const MainAppRoutes: React.SFC = (): JSX.Element =>
{
    return (
        <Switch>
            <Route exact path='/' component={HomePage} />
            <CustomerAppRoutes />
            <CarAppRoutes />
        </Switch>
    );

const CustomerAppRoutes: React.SFC = (): JSX.Element =>
{
    return (
        <Switch>
            <Route path='/customers' component={CustomersDisplayPage} />
            <Route path='/customers/:id' component={CustomersDisplayPage} />
        </Switch>
    );
};

const CarAppRoutes: React.SFC = (): JSX.Element =>
{
    return (
        <Switch>
            <Route path='/cars' component={CarDisplayPage} />
            <Route path='/cars/:id' component={CarDisplayPage} />
        </Switch>
    );
};

但是这会导致Caroutes不能正确路由。我尝试过使用Div,而这也不起作用。

6 个答案:

答案 0 :(得分:4)

在React 16中,您可以使用Fragments完成此操作:

const MainAppRoutes: React.SFC = (): JSX.Element => (
    <Switch>
        <Route exact path='/' component={HomePage} />
        <CustomerAppRoutes />
        <CarAppRoutes />
    </Switch>
);

const CustomerAppRoutes: React.SFC = (): JSX.Element => (
    <>
        <Route path='/customers' component={CustomersDisplayPage} />
        <Route path='/customers/:id' component={CustomersDisplayPage} />
    </>
);

const CarAppRoutes: React.SFC = (): JSX.Element => (
    <>
        <Route path='/cars' component={CarDisplayPage} />
        <Route path='/cars/:id' component={CarDisplayPage} />
    </>
);

答案 1 :(得分:3)

你可以把它放在单独的文件中,然后将它们映射到主文件

CustomerRoutes.js

import ...
export default [
    { path: '/customers', component: CustomersDisplayPage },
    { path: '/customers/:id', component: CustomersDisplayPage }
]

CarAppRoutes.js

import ...
export default [
    { path: '/cars', component: CarDisplayPage },
    { path: '/cars/:id', component: CarDisplayPage }
]

MainRoutes.js

import ...
import CarAppRoutes from 'wherever';
import CustomerRoutes from 'wherever';

...
<Switch>
    <Route exact path='/' component={HomePage} />
    { CustomerRoutes.map(props => <Route {...props} />) }
    { CarAppRoutes.map(props => <Route {...props} />) }
</Switch>

答案 2 :(得分:0)

我目前使用的解决方案是创建路径数组:

//routes.tsx
import * as React from 'react';

export interface IRoute { path: string, component: React.ComponentClass, exact?: boolean }

const CarRoutes: IRoute[] = [
   { path: '/cars', component: {CarDisplayPage} },
   { path: '/cars/:id', component: {CarDisplayPage} },
];

const CustomerRoutes: IRoute[] = [
    { path: '/customers', component: {CustomerDisplayPage} },
    { path: '/customers/:id', component: {CustomerDisplayPage} },
];

const AppRouting: React.SFC = (): JSX.Element =>
{
    const routes = []
        .concat(CarRoutes)
        .concat(CustomerRoutes);
    return (
        <Switch>
            <Route exact path='/' component={HomePage} />
            {routes.map(r => <Route path={r.path} exact={r.exact===true} path={r.path} key={r.path} />)}
        </Switch>
    );
};

答案 3 :(得分:0)

当我尝试使用react-router-5解决类似问题时,我发现了这个问题。片段对我不起作用,实际上,当我查看Switch组件实现内部时,我明白了为什么。片段仍然是一个反应组件,但Switch只希望Routes作为子代。

就我而言,我可以使用一种解决方法。

  1. 我使用功能组件返回Route数组。

  2. 我将函数组件称为函数而不是React组件。

如果有必要,在CustomerAppRoutes和CarAppRoutes中安装道具没有问题。

const MainAppRoutes = () => (
    <Switch>
        <Route exact path='/' component={HomePage} />
        {CustomerAppRoutes()}
        {CarAppRoutes()}
    </Switch>
);

const CustomerAppRoutes = () => ([
    <Route path='/customers' component={CustomersDisplayPage} />,
    <Route path='/customers/:id' component={CustomersDisplayPage} />
]);

const CarAppRoutes = () => ([
    <Route path='/cars' component={CarDisplayPage} />,
    <Route path='/cars/:id' component={CarDisplayPage} />
]);

答案 4 :(得分:0)

或仅将其映射为switch的子代

 <Switch>
    <Route exact path='/' component={HomePage} />
    {
       ['/customers', '/customers/:id'].map((p, i) => <Route key={i} path={p} component={CustomersDisplayPage} />)
    }
</Switch>

答案 5 :(得分:0)

晚了一点,但是要扩大已经说过的话:正确的是,将仅接受,而令人沮丧地不是常规的功能/类组件。

但是,我们可以通过扩展Route来满足该要求,以便能够创建一组抽象的路由:

MainRoutes.js

import ...
import CarAppRoutes from 'wherever';
import CustomerRoutes from 'wherever';

...
<Switch>
    <Route exact path='/' component={HomePage} />
    <CustomerAppRoutes />
</Switch>

CustomerAppRoutes.js

import ...

class CustomerAppRoutes extends Route { 
  constructor(props) {
    super(props);
  }

  // NB for Switch to accept our route as valid
  static defaultProps = { 
    path: "/customers",
  };


  render() {
    return (
      <React.Fragment>
         <Route path='/customers' component={CustomersDisplayPage} />
         <Route path='/customers/:id' component={CustomersDisplayPage} />
      </React.Fragment>
    )
  }
}

export default CustomerAppRoutes